//#include <stdio.h>
//
//int main()
//{
//    int n = 0;
//    scanf("%d",&n);
//    char str[n];
//    if(n < 3)
//    {
//        printf("0\n");
//        return 0;
//    }
//    scanf("%s",str);
//    char *prev = str;
//    int sum = 0;
//    while(*prev)
//    {
//        char *cur = prev + 1;
//        while(*cur)
//        {
//            char *next = cur + 1;
//            while(*next)
//            {
//                if(*prev != *cur && *cur == *next)
//                {
//                    ++sum;
//                }#include <stdio.h>
//
//                  int main()
//                {
//                    int n = 0;
//                    scanf("%d",&n);
//                    char str[n];
//                    if(n < 3)
//                    {
//                        printf("0\n");
//                        return 0;
//                    }
//                    scanf("%s",str);
//                    char *prev = str;
//                    int sum = 0;
//                    while(*prev)
//                    {
//                        char *cur = prev + 1;
//                        while(*cur)
//                        {
//                            char *next = cur + 1;
//                            while(*next)
//                            {
//                                if(*prev != *cur && *cur == *next)
//                                {
//                                    ++sum;
//                                }
//                                ++next;
//                            }
//                            ++cur;
//                        }
//                        ++prev;
//                    }
//                    printf("%d\n",sum);
//                    return 0;
//                }
//                ++next;
//            }
//            ++cur;
//        }
//        ++prev;
//    }
//    printf("%d\n",sum);
//    return 0;
//}
//#include "test.h"
//2023.11.14
//using namespace std;
//class Date
//{
//public:
//
//private:
//
//};
//int main()
//{
//
//    return 0;
//}
//using namespace std;
//inline int Add(int x, int y)
//{
//    return x + y;
//}
//inline int Add(char x, int y)
//{
//    1;
//    1;
//    1;
//    int c = x + y;
//    c = x + y;
//    c = x + y;
//    c = x + y;
//    c = x + y;
//    c = x + y;
//    c = x + y;
//    c = x + y;
//    c = x + y;
//    c = x + y;
//    c = x + y;
//    c = x + y;
//
//
//    return x + y;
//}
//char Add(char x, char y)
//{
//    return x + y;
//}
//int main()
//{
//    Add(1,2);
//    Add('w',2);
//    Add('1','2');
//    return 0;
//}
//using namespace std;
//typedef char* pstring;
//int main()
//{
//    const pstring p1 = nullptr;
//    const pstring* p2;
//    cout << typeid(p1).name() << endl;
//    cout << typeid(p2).name() << endl;
//    return 0;
//}
//using namespace std;
//int main()
//{
//    int a[] = {1,2,3};
//    for(auto m:a)
//    {
//        cout << m << ' ';
//    }
//    cout << endl;
//    return 0;
//}
//using std::cout;
//using std::endl;
//class Stack
//{
//public:
//    Stack()
//    {
//        _a = nullptr;
//        _size = 0;
//        _capacity = 0;
//    }
//    void Creat()
//    {
//        int new_capacity = _capacity==0 ? 4 : _capacity*2;
//        int *room = (int*)realloc(_a,sizeof(int)*new_capacity);
//        if(room == nullptr)
//        {
//            perror("realloc fail");
//            exit(-1);
//        }
//        _a = room;
//        _capacity = new_capacity;
//    }
//    void Push(int num)
//    {
//        if(_size == _capacity)
//        {
//            Creat();
//        }
//        _a[_size++] = num;
//    }
//    ~Stack()
//    {
//        free(_a);
//
//    }
//private:
//    int *_a;
//    int _size;
//    int _capacity;
//};
//int main()
//{
//    Stack st;
//    st.Push(3);
//    st.Push(3);
//    st.Push(3);
//    st.Push(3);
//    st.Push(3);
//    return 0;
//}
//int main()
//{
//    Date date(2023,11,14);
//    date.Print();
//    return 0;
//}
//using namespace std;
//class Date
//{
//public:
//    ~Date()
//    {
//        cout << "~Date" << endl;
//    }
//private:
//    int _year;
//    int _month;
//    int _day;
//};
//Date a;
//int main()
//{
//    Date b;
//     Date c;
//    return 0;
////}
//using namespace std;
//class A
//{
//public:
//    void Printf()
//    {
//        cout << _a << endl;
//    }
//private:
//    int _a;
//};
//int main()
//{
//    A *a = nullptr;
//    a->Printf();
//    return 0;
//}
//}
//using namespace std;
//class Date
//{
//public:
//    void Init(int _year, int _month, int _day)
//    {
//        _year = _year;
//        _month = _month;
//        _day = _day;
//    }
//    void Printf()
//    {
//        cout << _year << '-' << _month << '-' << _day << endl;
//    }
//private:
//    int _year;
//    int _month;
//    int _day;
//};
//int main()
//{
//    Date date;
//    date.Init(2023,11,14);
//    date.Printf();
//    return 0;
//}
//#include <iostream>
//using namespace std;
//class Date
//{
//public:
//    Date(int year, int month, int day)
//    {
//        _year = year;
//        _month = month;
//        _day = day;
//    }
//    void Printf()
//    {
//        cout << _year << '-' << _month << '-' << _day << endl;
//    }
//private:
//    int _year;
//    int _month;
//    int _day;
//};
//int main()
//{
//    Date date1(2023,11,14);
//    date1.Printf();
//    Date date2(2022,11,14);
//    date2.Printf();
//    return 0;
//}
//#include <stdio.h>
//typedef struct Date
//{
//    int _year;
//    int _month;
//    int _day;
//}Date;
//void Init(Date *pd,int year, int month, int day)
//{
//    pd->_year = year;
//    pd->_month = month;
//    pd->_day = day;
//}
//void Print(Date *pd)
//{
//    printf("%d-%d-%d\n",pd->_year,pd->_month,pd->_day);
//}
//int main()
//{
//    Date date1;
//    Init(&date1,2023,11,14);
//    Print(&date1);
//
//    Date date2;
//    Init(&date2,2022,11,14);
//    Print(&date2);
//    return 0;
//#include <iostream>
//using namespace std;
//class Date
//{
//public:
//    Date(int year, int month, int day)
//    {
//       this-> _year = year;
//       this->_month = month;
//       this-> _day = day;
//    }
//    void Printf()
//    {
//        cout << this-> _year << '-' << this-> _month << '-' << this-> _day << endl;
//    }
//private:
//    int _year;
//    int _month;
//    int _day;
//};
//int main()
//{
//    Date date1(2023,11,14);
//    date1.Printf();
//    Date date2(2022,11,14);
//    date2.Printf();
//    return 0;
//}
//#include <iostream>
//using namespace std;
//// 1.下面程序编译运行结果是？ A、编译报错 B、运行崩溃 C、正常运行
//class A
//{
//public:
//    void Print()
//    {
//        cout << "Print()" << endl;
//    }
//private:
//    int _a;
//};
//int main()
//{
//    A* p = nullptr;
//    p->Print();
//    return 0;
//}
//#include <iostream>
//using namespace std;
//class Date
//{
//public:
//    Date(int year, int month, int day)
//    {
//        _year = year;
//        _month = month;
//        _day = day;
//    }
//    static void Change(int year)
//    {
//        _year = year;
//    }
//    void Printf()
//    {
//        cout << _year << '-' << _month << '-' << _day << endl;
//    }
//private:
//    int _year;
//    int _month;
//    int _day;
//};
//int main()
//{
//    Date date1(2023,11,14);
//    date1.Printf();
//    Date date2(2022,11,14);
//    date2.Printf();
//    return 0;
//}
//#include <iostream>
//using std::cout;
//using std::endl;
//class Date
//{
//public:
////    Date()
////    {
////        _year = 2023;
////        _month = 11;
////        _day = 14;
////    }
//    void Print()
//    {
//        cout << _year << '-' << _month << '-' << _day << endl;
//    }
//private:
//    int _year;
//    int _month;
//    int _day;
//};
//int main()
//{
//    Date date;
//    date.Print();
//}
//#include <iostream>
//using std::cout;
//using std::endl;
//class Date
//{
//public:
//    Date()
//    {
//        _year = 2023;
//        _month = 11;
//        _day = 14;
//    }
//    void Print()
//    {
//        cout << _year << '-' << _month << '-' << _day << endl;
//    }
//private:
//    int _year = 2022;
//    int _month = 11;
//    int _day = 14;
//};
//int main()
//{
//    Date date;
//    date.Print();
//}
//#include "test.h"
//using std::cout;
//using std::endl;
//
//int main()
//{
////    MyQueue mq(1);
////    Stack st;
//    return 0;
//}
//////////////////////////2023.11.15
//#include <iostream>
//using namespace std;
//
//int main()
//{
//    return 0;
//}
//
//#include "test.h"
//using std::cout;
//using std::endl;
//
//int main()
//{
////    MyQueue mq(1);
//    Stack st;
//    st.Push(2);
//    st.Push(3);
//    st.Push(4);
//    st.Push(5);
//    st.Push(6);
//    st.Print();
//
//    Stack st2(st);
//    st2.Print();
//    return 0;
//}
/*
 * //
// Created by 王有东 on 2023/11/9.
//

//#include "test.h"
//void Stack:: Init()
//{
//    a = nullptr;
//    val = 0;
//    capacity = 0;
//}
//void Stack::Push(int num)
//{
//    ///////
//}
//void Date::Assign(int year)
//{
//    year = year;
//}
//void Date::Printf()
//{
//    cout << _year << "-" << _month << "-" << _day << endl;
//}
//Date::Date(int year, int month, int day)
//{
//    _year = year;
//    _month = month;
//    _day = day;
//}
//
//void Date::Print()
//{
//    cout << _year << '-' << _month << '-' << _day << endl;
//}
//#include "test.h"
//Stack::Stack()
//{
//    _a = (int*)malloc(sizeof(int) * 4);
//    if(_a == nullptr)
//    {
//        perror("malloc fail");
//        exit(-1);
//    }
//    _size = 0;
//    _capacity = 4;
//}
//Stack::Stack(const Stack &new_st)
//{
//    _a = (int*) malloc(sizeof(int) * (new_st._capacity));
//    if(_a == nullptr)
//    {
//        perror("Stack(Stack &new_st) malloc fail");
//        exit(-1);
//    }
//    memcpy(_a,new_st._a,sizeof(int)*new_st._size);
//
//    _size = new_st._size;
//    _capacity = new_st._capacity;
//}
//void Stack:: Create()
//{
//    int *tmp = (int*) realloc(_a,sizeof(int) * _capacity*2);
//    if(tmp == nullptr)
//    {
//        perror("malloc fail");
//        exit(-1);
//    }
//    _a = tmp;
//    _capacity = _capacity*2;
//}
//void Stack::Push(int num)
//{
//    if(_capacity == _size)
//        Create();
//    _a[_size++] = num;
//}
//void Stack::Print()
//{
//    for (int i = 0; i < _size; ++i)
//    {
//        cout << _a[i] << ' ';
//    }
//    cout << endl;
//}
//Stack::~Stack()
//{
//    free(_a);
//    _capacity = 0;
//    _size = 0;
//    _a = nullptr;
//}
////MyQueue::MyQueue(int a)
////{
////    a = 0;
////}/
 */
//#include "test.h"
//void Test1()
//{
//    Date date1(2006,9,16);
//    Date date2(2006,4,16);
//    if(date1 > date2)
//        cout << "date1 > date2" << endl;
//    if(date1 < date2)
//        cout << "date1 < date2" << endl;
//    if(date1 <= date2)
//        cout << "date1 <= date2" << endl;
//    if(date1 >= date2)
//        cout << "date1 >= date2" << endl;
//    if(date1 != date2)
//        cout << "date1 != date2" << endl;
//    if(date1 == date2)
//        cout << "date1 == date2" << endl;
//
//    Date date3 = date1;
//    date1.Print();
//    date3.Print();
//}
//void Test2()
//{
//    Date date2(2023,11,15);
//    Date date1(1996,6,29);
//    date2.Print();
//    Date date3 = date2 - 100;
//    date3.Print();
//    Date date4 = date2 - 10000;
//    date4.Print();
//    Date date5 = date2 + 100;
//    date5.Print();
//    Date date6 = date1 + 10000;
//    date6.Print();
//
//
//}
//void Test3()
//{
//    Date date1(2022,6,29);
//    Date date2;
//    date2 = date1;
//    date1.Print();
//    date2.Print();
//}
//int main()
//{
//    Test1(); //> < = ≤ ≥ != =
//    Test2();//日期+，+=，-，-=，-日期
////    Test3();//++，--
//    return 0;
//}
/*

//全缺省的构造函数
Date::Date(int year, int month, int day)
{
    assert(year >= 1 && month >= 1 || month <= 12 || day >= 1 && day <= GetMonthDay(year,month));
    _year = year;
    _month = month;
    _day = day;
}

//拷贝构造函数
Date::Date(const Date &new_date)
{
    _year = new_date._year;
    _month = new_date._month;
    _day = new_date._day;
}

//析构函数
Date::~Date()
{
    _year = 0;
    _month = 0;
    _day = 0;
}

//打印日期
void Date::Print()
{
    cout << _year << '-' << _month << '-' << _day << endl;
}

//赋值运算符重载 =
//写返回值是为了连续赋值
Date& Date::operator=(const Date& another)
{
    if(this != &another)
    {
        _year = another._year;
        _month = another._month;
        _day = another._day;
    }
    return *this;
}



//运算符重载 ==
bool Date::operator==(const Date& another)
{
    return _year == another._year && _month == another._month && _day == another._day;
}
//运算符重载 !=
bool Date::operator!=(const Date& another)
{
    return !(*this == another);
}

//运算符重载 >
bool Date::operator>(const Date& another)
{
    if(_year > another._year)
    {
        return true;
    }
    else if(_year == another._year && _month > another._month)
    {
        return true;
    }
    else if(_year == another._year && _month == another._month && _day > another._day)
    {
        return true;
    }
    return false;
}

//运算符重载 >=
bool Date::operator>=(const Date& another)
{
    return *this > another || *this == another;
}

//运算符重载 <
bool Date::operator<(const Date& another)
{
    return !(*this >= another);
}

//运算符重载 <=
bool Date::operator<=(const Date& another)
{
    return !(*this > another);
}


//获取某年某月的天数
int Date::GetMonthDay(int year, int month)
{
    assert(year >= 1 && month >= 1 && month <= 12);

    int day[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
    if(month == 2 && ((year%4 == 0 && year%100 != 0) || (year%400 == 0)))
        return 29;
    return day[month];
}
//日期+=天数
Date& Date::operator+=(int day)
{
    if(day < 0)
    {
        return *this -= -day;
    }

    _day += day;
    while(_day > GetMonthDay(_year,_month))
    {
        _day -= GetMonthDay(_year,_month);
        _month++;

        if(_month == 13)
        {
            _year++;
            _month = 1;
        }
    }
    return *this;
}

//日期+天数
Date Date::operator+(int day)
{
    Date date(*this);
    date += day;
    return date;
}

//日期-=天数
Date& Date::operator-=(int day)
{
    if(day < 0)
    {
        return *this += -day;
    }

    _day -= day;
    while(_day <= 0)
    {
        --_month;
        if(_month == 0)
        {
            --_year;
            _month = 12;
        }
        _day += GetMonthDay(_year,_month);
    }


    assert(_year > 0 && _month > 0 && _month < 13 && _day <= GetMonthDay(_year,_month));

    return *this;
}

//日期-天数
Date Date::operator-(int day)
{
    Date date(*this);
    date -= day;

    return date;
}

int GetYearDay(int year)
{
    if( (year%4 == 0 && year%100 != 0) || year%400 == 0)
        return 366;
    else
        return 365;
}
//日期-日期（简单但相对低效）
int Date::operator-(const Date& another)
{
    Date max = *this;
    Date min = another;
    int flag = 1;
    int dif = 0;

    if(*this < another)
    {
        max = another;
        min = *this;
        flag = -1;
    }

    while(min < max)
    {
        ++dif;
        ++min;
    }

    dif *= flag;
    return dif;
}
//日期-日期（麻烦但高效）
//int Date::operator-(const Date& another)
//{
//    assert(*this > another);
//
//    Date big_date(*this);
//    Date small_date(another);
//    ////////////////////////////////////////
//    int big_day = 0;
//    int big_year = big_date._year - 1;
//    while (big_year >= small_date._year)
//    {
//        big_day += GetYearDay(big_year);
//        big_year--;
//    }
//
//    big_date._month--;
//    while(big_date._month != 0)
//    {
//        big_day += GetMonthDay(big_date._year,big_date._month);
//        big_date._month--;
//    }
//
//    big_day += big_date._day;
//    ////////////////////////////////////////
//    int small_day = 0;
//    small_date._month--;
//    while(small_date._month != 0)
//    {
//        small_day += GetMonthDay(small_date._year,small_date._month);
//        small_date._month--;
//    }
//
//    small_day += small_date._day;
//    ////////////////////////////////////////
//    return big_day - small_day;
//}

//前置++
Date& Date::operator++()
{
    *this += 1;
    return *this;
}

//后置++
Date Date::operator++(int)
{
    Date tmp(*this);
    *this += 1;
    return tmp;
}

//前置--
Date& Date::operator--()
{
    *this -= 1;
    return *this;
}
//后置--
Date Date::operator--(int)
{
    Date tmp(*this);
    *this -= 1;
    return tmp;
}/
 class Date
{
public:
    //全缺省的构造函数
    Date(int year = 2003, int month = 11, int day = 15);
    //拷贝构造函数
    Date(const Date& new_date);
    //析构函数
    ~Date();
    //赋值运算符重载
    Date& operator=(const Date& another);

    //打印日期
    void Print();
    //获取某年某月的天数
    int GetMonthDay(int year, int month);

    //运算符重载 >
    bool operator>(const Date& another);
    //运算符重载 ==
    bool operator==(const Date& another);
    //运算符重载 <
    bool operator<(const Date& another);
    //运算符重载 >=
    bool operator>=(const Date& another);
    //运算符重载 <=
    bool operator<=(const Date& another);
    //运算符重载 !=
    bool operator!=(const Date& another);

    //日期+天数
    Date operator+(int day);
    //日期+=天数
    Date& operator+=(int day);
    //日期-=天数
    Date& operator-=(int day);
    //日期-天数
    Date operator-(int day);
    //日期-日期
    int operator-(const Date& another);

    //前置++
    Date& operator++();
    //后置++
    Date operator++(int);
    //前置--
    Date& operator--();
    //后置--
    Date operator--(int);

private:
    int _year;
    int _month;
    int _day;
};
 //using namespace std;
//inline int Add(int x,int y)
//{
//    return x + y;
//}


//class Stack
//{
//private:
//    int val;
//    int capacity;
//    int* a;
//public:
//    void Init();
//    void Push(int num);
//};
//class Date
//{
//public:
//    int _year;
//    int _month;
//    int _day;
//
//    void Printf();
//};
//inline void Add(double x,double y)
//{
//    cout << x + y << endl;
//}
//class Date
//{
//public:
//    Date(int year, int month, int day); //初始化
//    void Print();
//private:
//    int _year;
//    int _month;
//    int _day;
//};
//class Stack
//{
//public:
//    Stack();
//    Stack(const Stack &new_st);
//    void Create();
//    void Push(int num);
//    void Print();
//    ~Stack();
//private:
//    int *_a;
//    int _size;
//    int _capacity;
//};
//class MyQueue
//{
//public:
//    MyQueue(int a);
//private:
//    Stack st1;
//    Stack st2;
//    int a;
//};
 */
//#include "test.h"
//void Test1()
//{
//    Date today(2023, 2, 28);
//    Date yesterday(2023,2,28);
//    if(today > yesterday)
//        cout << "today > yesterday" << endl;
//    if(today < yesterday)
//        cout << "today < yesterday" << endl;
//    if(today == yesterday)
//        cout << "today == yesterday" << endl;
//    if(today <= yesterday)
//        cout << "today <= yesterday" << endl;
//    if(today >= yesterday)
//        cout << "today >= yesterday" << endl;
//    if(today != yesterday)
//        cout << "today != yesterday" << endl;
//
//    Date date = today;
//    today.Print();
//    date.Print();
//}
//void Test2()
//{
//    Date today(2023, 11, 16);
//    Date yesterday(2023,11,16);
//
//    Date date1 = today + -10000;
//    Date date2 = yesterday - -10000;
//    date1.Print();
//    date2.Print();
//
//    today -= -10000;
//    today.Print();
//    yesterday += -10000;
//    yesterday.Print();
////     int dif = yesterday - today;
////     cout << dif << endl;
//
//}
//void Test3()
//{
//    Date today(2023, 11, 16);
//    Date yesterday(2023,11,16);
//    Date date = today++;
//    date.Print();
//    today.Print();
//    ++today;
//    today.Print();
//
//    yesterday--;
//    yesterday.Print();
//    --yesterday;
//    yesterday.Print();
//
//}
//int main()
//{
////    Test1(); //> == >= < <= != =
////    Test2(); //+天数 -天数 +=天数 -=天数 -日期
////    Test3(); // ++ --
//
//    return 0;
//}
//#include "test.h"
//void Test()
//{
//    Date today(2003,10,16);
//    Date yesterday(2006,1,2);
////    cout << date1 << date2 << date3;
////    cin >> date1 >> date2 >> date3;
////    cout << date1 << date2 << date3;
//    if(today > yesterday)
//        cout << "today > yesterday" << endl;
//    if(today < yesterday)
//        cout << "today < yesterday" << endl;
//    if(today == yesterday)
//        cout << "today == yesterday" << endl;
//    if(today <= yesterday)
//        cout << "today <= yesterday" << endl;
//    if(today >= yesterday)
//        cout << "today >= yesterday" << endl;
//    if(today != yesterday)
//        cout << "today != yesterday" << endl;
//}
//void Test2()
//{
//    const Date date1(2003,10,16);
//    Date date2(2006,4,16);
////    date2.Print();
////    date1.Print();
//}
//int main()
//{
//    Test();
////    Test2();
//    return 0;
//}
//#include <iostream>
//using namespace std;
//enum X
//{
//    x1,
//    x2,
//    x3,
//    x4 = 10,
//    x5,
//    x6,
//}X;
//int main()
//{
//    enum Y {
//        x1 = 1,
//        x2 = 20,
//        x3 = 3,
//        x4 = 4,
//    }Y;
//    cout << Y << endl;
//    return 0;
////}
//#include <iostream>
//using namespace std;
//
//class A
//{
//public:
//    explicit A(int ca = 1, int cb = 2, int cc = 3, int cd = 4)
//        : a(ca)
//        , b(cb)
//        , d(cd)
//    {}
//    friend ostream& operator<<(ostream& out, const A& a);
//    ~A()
//    {
//        a = 0;
//        b = 0;
//    }
//private:
//    int a;
//    int& b;
//    const int d;
//};
//ostream& operator<<(ostream& out, const A& a)
//{
//    out << a.a << endl << a.b << endl << a.d << endl;
//    return out;
//}
//
//class B
//{
//public:
//    B(int ce, A& ca)
//        : e(ce)
//        , a(ca)
//    {}
//    friend ostream& operator<<(ostream& out, B& b);
//
//private:
//    int e;
//    A a;
//};
//ostream& operator<<(ostream& out, B& b)
//{
//    out << b.e << endl << b.a << endl;
//    return out;
//}
//
//int main()
//{
//    A class_a(5,6,7,8);
////    B class_b(10, class_a);
//    cout << class_a;
////    cout << class_b;
//
//}
//class A
//{
//public:
//    A(int& a)
//        :_a(a)
//    {}
//    friend ostream& operator<<(ostream& out, A& a);
//private:
//    int& _a;
//};
//ostream& operator<<(ostream& out, A& a)
//{
//    out << a._a;
//    return out;
//}
//class B
//{
//public:
//    B(int a, int ref)
//        :_aobj(a)
//        ,_ref(ref)
//        ,_n(10)
//    {}
//    friend ostream& operator<<(ostream& out, B& b);
//private:
//    A _aobj; // 没有默认构造函数
//    int& _ref; // 引用
//    const int _n; // const
//};
//ostream& operator<<(ostream& out, B& b)
//{
//    out << b._aobj << endl << b._ref << endl << b._n << endl;
//    return out;
//}
//int main()
//{
//    int c = 10;
//    A a(c);
//    cout << a;
////    B b(10,30);
////    cout << b;
//    return 0;
//}
//#include <iostream>
//using namespace std;
//class Date
//{
//public:
//    Date(int year = 1, int month = 1, int day = 1, const int &copy = 1)
//        : _year(year)
//        , _month(month)
//        , _day(day)
//        , _copy(copy)
//    {}
//private:
//    int _year;
//    int _month;
//    int _day;
//    int *_a;
//    const int& _copy;
//
//};
//int main()
//{
//    Date date1(2003, 10, 16, 2023);
//    return 0;
//}
//#include <iostream>
//using namespace std;
//class A
//{
//public:
//    A(int a)
//        :_a(a)
//    {}
//private:
//    int _a;
//};
//class B
//{
//public:
//    B(int b, A& a)
//        :_b(b)
//        ,_A(a)
//    {}
//private:
//    int _b;
//    A _A;
//};
//int main()
//{
//    A a(20);
//    B b(2,a);
//    return 0;
//}
/*
 * using namespace std;
class Date
{
public:
    //全缺省构造函数
    Date(int year = 1, int month = 1, int day = 1);
    //拷贝构造函数
    Date(const Date& date);
    //析构函数
    ~Date();
    //赋值运算符重载=
    Date& operator=(const Date& date);

    //运算符重载 >
    bool operator>(const Date& another) const;
    //运算符重载 ==
    bool operator==(const Date& another) const;
    //运算符重载 <
    bool operator<(const Date& another) const;
    //运算符重载 >=
    bool operator>=(const Date& another) const;
    //运算符重载 <=
    bool operator<=(const Date& another) const;
    //运算符重载 !=
    bool operator!=(const Date& another) const;
    //运算符重载


    //取某年某月的天数
    int GetMonthDay(int year, int month);
    //日期+=天数
    //日期+天数
    //日期-=天数
    //日期-天数
    //日期-日期


    //前置++
    //后置++
    //前置--
    //后置--

    //打印

    //友元函数
    friend ostream& operator<<(ostream& out, Date& date);
    friend istream& operator>>(istream& in, Date& date);
private:
    int _month;
    int _day;
    int _year;
};
//运算流重载 <<
ostream& operator<<(ostream& out, Date& date);
//运算流重载 >>
istream& operator>>(istream& in, Date& date);
//
/
 //全缺省构造函数
Date::Date(int year, int month, int day)
    : _year(year)
    , _month(month)
    , _day(day)
{
    if(year < 1 || month < 1 || month > 12 || _day > GetMonthDay(year, month))
    {
        cout << "非法日期" << endl;
        assert(false);
    }
}
//拷贝构造函数
Date::Date(const Date& date)
{
    _year = date._year;
    _month = date._month;
    _day = date._day;
}
//析构函数
Date::~Date()
{
    _year = 0;
    _month = 0;
    _day = 0;
}
//赋值运算符重载
Date& Date::operator=(const Date& date)
{
    if(this != &date)
    {
        _year = date._year;
        _month = date._month;
        _day = date._day;
    }
    return *this;
}


//    //运算符重载 >
bool Date::operator>(const Date& another) const
{
    if(_year > another._year)
        return true;
    else if(_year == another._year && _month > another._month)
        return true;
    else if(_year == another._year && _month == another._month && _day > another._day)
        return true;
    return false;
}
//    //运算符重载 ==
bool Date::operator==(const Date& another) const
{
    return _year == another._year && _month == another._month && _day == another._day;
}
//    //运算符重载 <
bool Date::operator<(const Date& another) const
{
    return !(*this > another || *this == another);
}
//    //运算符重载 >=
bool Date::operator>=(const Date& another) const
{
    return !(*this < another);
}
//    //运算符重载 <=
bool Date::operator<=(const Date& another) const
{
    return !(*this > another);
}
//    //运算符重载 !=
bool Date::operator!=(const Date& another) const
{
    return !(*this == another);
}


//取某年某月的天数
int Date::GetMonthDay(int year, int month)
{
    int monthday[] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
    if(month == 2 && ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0))
    {
        return 29;
    }
    return monthday[month];
}
//日期+=天数

//日期+天数

//日期-=天数

//日期-天数

//日期-日期



//前置++

//后置++

//前置--

//后置--


//打印


//运算流输出<<
ostream& operator<<(ostream& out, Date& date)
{
    out << date._year << "年" << date._month << "月" << date._day << "日" << endl;
    return out;
}
//运算流输入>>
istream& operator>>(istream& in, Date& date)
{
    in >> date._year >> date._month >> date._day;
    return in;
}
 */
/*

using namespace std;
class Date
{
public:
    Date(int year, int month, int day);
    int GetMonthDay(int year, int month);
    Date& operator+(int day);
    void Print();
private:
    int _year;
    int _month;
    int _day;
};
void Date::Print()
{
    printf("%04d-%02d-%02d\n", _year, _month, _day);
}
Date& Date::operator+(int day)
{
    _day += day;
    while(_day > GetMonthDay(_year, _month))
    {
        _day -= GetMonthDay( _year, _month);
        ++_month;
        if(_month == 13)
        {
            ++_year;
            _month = 1;
        }
    }
    return *this;
}
Date::Date(int year, int month, int day)
{
    if(year < 1 || month < 1 || month > 12 || day > GetMonthDay(year, month))
    {
        cout << "非法日期" << endl;
        assert(false);
    }

    _year = year;
    _month = month;
    _day = day;
}
int Date::GetMonthDay(int year, int month)
{
    int monthday[] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
    if(month == 2 && ((year % 4 == 0 && year % 100 != 0)|| year % 400 == 0))
        return 29;
    return monthday[month];
}
int main()
{
    int a, b;
    while (cin >> a >> b)
    {
        Date date(a, 1, 0);
        Date yearmonth = date + b;
        yearmonth.Print();
    }
    return 0;
}*/
//}

//#include <iostream>
//#include <iostream>
//using namespace std;
//class Date
//{
//public:
//    Date(int year = 1, int month = 1, int day = 1)
//        : _year(year)
//        , _day(month)
//        , _month(day)
//    {}
//private:
//    int _year;
//    int _month;
//    int _day;
//};
//int main()
//{
//    Date date(2003, 10, 16);
//    return 0;
//}
//#include <iostream>
//using namespace std;
//class Date
//{
//public:
//    Date(int year = 2, int month = 1, int day = 1)
//            : _year(year)
//            , _month(month)
//            , _day(day)
//    {}
//    void Print()
//    {
//        cout << _year << "年" << _month << "月" << _day << "日" << endl;
//    }
//private:
//    int _year;
//    int _month;
//    int _day;
//};
//int main()
//{
//    Date date = {2003, 10, 16};
//    date.Print();
//    return 0;
//}
//#include <iostream>
//using namespace std;
//class A
//{
//public:
//    A() { ++_scount; }
//    A(const A& t) { ++_scount; }
//    ~A() { --_scount; }
//    static int GetACount() { return _scount; }
//private:
//    static int _scount;
//};
//
//int A::_scount = 0;
//
//void TestA()
//{
//    cout << A::GetACount() << endl;
//    A a1, a2;
//    A a3(a1);
//    cout << A::GetACount() << endl;
//}
//int main()
//{
//    TestA();
//    return 0;
//}
//#include <iostream>
//using namespace std;
//
//namespace wyd
//{
//    int count = 0;
//}
//
//class Date
//{
//public:
//    Date()
//    {
//        wyd::count++;
//        _count++;
//    }
//    Date(const Date& date)
//    {
//        wyd::count++;
//        _count++;
//    }
//    static int GetCount()
//    {
//        return _count;
//    }
//private:
//    int _year;
//    int _month;
//    int _day;
//    static int _count;
//};
//int Date::_count = 0;
//
//int main()
//{
//    Date date;
//    Date date2(date);
//    cout << wyd::count << endl;
//    cout << date.GetCount() << endl;
//    return 0;
//}
//
//#include <iostream>
//using namespace std;
//class Date
//{
//public:
//    Date()
//    {
//        _count++;
//    }
//    Date(const Date& date)
//    {
//        _count++;
//    }
//    static int GetCount()
//    {
//        return _count;
//    }
//private:
//    int _year;
//    int _month;
//    int _day;
//    static int _count;
//};
//int Date::_count = 0;
//
//int main()
//{
//    Date date;
//    Date date2(date);
//    cout << Date().GetCount() - 1;
//    return 0;
//}
//#include <iostream>
//#include <istream>
//using namespace std;
//class Date
//{
//public:
//    friend istream& operator<<(istream& in, Date& date);
//private:
//    int _year;
//    int _month;
//    int _day;
//
//};
//istream& operator<<(istream& in, Date& date)
//{
//    in << date._year << date._month << date._day;
//    return in;
//}
//int main()
//{
//    Date date;
//    cin << date;
//
//    return 0;
//}
//#include <iostream>
//#include <istream>
//using namespace std;
//class Date
//{
//public:
//    Date& operator++();
//    bool operator<(const Date& another) const;
//    int operator-(const Date& another);
//    Date& operator+=(int day);
//    int GetMonthDay(int year, int month);
//    friend istream& operator>>(istream& in, Date& date);
//
//private:
//    int _year;
//    int _month;
//    int _day;
//    static int n;
//
//};
//int Date::n = 0;
//istream& operator>>(istream& in, Date& date)
//{
//    in >> date._year >> date._month >> date._day;
//    return in;
//}
//bool Date::operator<(const Date &another) const
//{
//    if(_year < another._year)
//        return true;
//    else if(_year == another._year && _month < another._month)
//        return true;
//    else if(_year == another._year && _month == another._month && _day < another._day)
//        return true;
//    else
//        return false;
//}
//int Date::GetMonthDay(int year, int month)
//{
//    int monthday[] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
//    if(month == 2 && ((year % 4 == 0 && year % 100 != 0)|| year % 400 == 0))
//        return 29;
//    return monthday[month];
//}
//Date& Date::operator+=(int day)
//{
//    _day += day;
//    if(_day > GetMonthDay(_year, _month))
//    {
//        _day -= GetMonthDay(_year, _month);
//        ++_month;
//        if(_month == 13)
//        {
//            ++_year;
//            _month = 1;
//        }
//    }
//    return *this;
//}
//Date& Date::operator++()
//{
//    *this += 1;
//    return *this;
//}
//int Date::operator-(const Date &another)
//{
//    Date max(*this);
//    Date min(another);
//    if(max < min)
//    {
//        max = another;
//        min = *this;
//    }
//    while(min < max)
//    {
//        ++min;
//        ++n;
//    }
//    if(n == 1)
//        return 2;
//    else
//        return n;
//}
//int main()
//{
//    Date date1;
//    cin >> date1;
//    Date date2;
//    cin >> date2;
//    int dif = date1 - date2;
//    cout << dif << endl;
//    return 0;
//}
//#include <iostream>
//using namespace std;
//class Date
//{
//public:
//    Date(int year)
//    {
//
//        _year = year;
//    }
//    void Print()
//    {
//        cout << _year << endl;
//    }
//private:
//    int _year;
//};
//static Date date(2003);
//int main()
//{
//    date.Print();
//}
//#include <iostream>
//using namespace std;
//class A
//{
//public:
//    A(int a = 0)
//    {
//        cout << "A()" << endl;
//    }
//private:
//    int _a;
//};
//class B
//{
//public:
//    B(int a)
//    {
//        cout << "B()" << endl;
//    }
//private:
//    int _b;
//    A _A;
//};
//int main()
//{
//    B b(2);
//    return 0;
//#include <iostream>
//using namespace std;
//class A
//{
//public:
//    void Print()
//    {
//        cout << "Print()" << endl;
//    }
//private:
//    double _a;
//
//    class B
//    {
//    private:
//        int _b;
//    };
//};
//
//int main()
//{
//    cout << sizeof(A) << endl;
//    return 0;
//}
/////////////////////////////////////////////////
//#include <iostream>
//using namespace std;
//class Date
//{
//public:
//    void Init(int year, int month, int day)
//    {
//        _year = year;
//        _month = month;
//        _day = day;
//    }
//    void Print()
//    {
//        cout << _year << "年" << _month << "月" << _day << "日" << endl;
//    }
//private:
//    int _year;
//    int _month;
//    int _day;
//};
//int main()
//{
//    Date date;
//    date.Init(2023, 11, 20);
//    date.Print();
//    return 0;
//}
//#include <iostream>
//using namespace std;
//class Date
//{
//public:
//    Date(int year, int month, int day)
//        : _year(year)
//        , _month(month)
//        , _day(day)
//    {}
//private:
//    int _year;
//    int _month;
//    int _day;
//};
//int main()
//{
//    Date date(2023, 11, 20);
//    return 0;
//}
//#include <stdio.h>
//int main()
//{
//    int a[][3] = {};
//    unsigned char c = '\xaa';
//    printf("%c\n",c);
//    return 0;
//}
//int z = 2
//z    x    y
//3(2) 1    4
//2(1) 2    3
//1(0) 3    2
//0(-1)
//#include <iostream>
//using namespace std;
//class Date
//{
//public:
//    Date()
//    {
//        _year = 3;
//        _year = 6;
//    }
//    void Print()
//    {
//        cout << _year << endl;
//    }
//private:
//    int _year;
//    int _month;
//    int _day;
//};
//int main()
//{
//    Date date;
//    date.Print();
//    return 0;
//}
//#include <iostream>
//using namespace std;
//class Date
//{
//public:
//    Date(int day)
//        :_day(day)
//    {}
//private:
//    int& _day;
//};
//int main()
//{
//    Date date(16);
//    return 0;
//}
//class Time
//{
//    friend class Date;  // 声明日期类为时间类的友元类，则在日期类中就直接访问Time类中的私有成员变量
//public:
//    Time(int hour = 0, int minute = 0, int second = 0)
//            : _hour(hour)
//            , _minute(minute)
//            , _second(second)
//            ,
//    {}
//
//private:
//    int _hour;
//    int _minute;
//    int _second;
//
//};
//class Date
//{
//public:
//
//    Date(int year = 1900, int month = 1, int day = 1)
//            : _year(year), _month(month), _day(day)
//    {}
//    void SetTimeOfDate(int hour, int minute, int second)
//    {
//        // 直接访问时间类私有的成员变量
//        _t._hour = hour;
//        _t._minute = minute;
//        _t._second = second;
//    }
//private:
//    int _year;
//    int _month;
//    int _day;
//    Time _t;
//}
//struct stduent
//{
//    int no;
//    char name[20];
////};
//#include <stdio.h>
//#include <stdlib.h>
//typedef struct List
//{
//    struct List* next;
//    int num;
//    int m;
//}SL;
//void Init(SL* plist)
//{
//    plist->next = plist;
//    plist->num = 0;
//    plist->m = 0;
//}
//void SLPush(SL* plist, int i, int j)
//{
//    SL *newcode = (SL*)malloc(sizeof(SL));
//    if(plist->next == plist)
//    {
//        plist->next = newcode;
//        newcode->next = plist;
//        newcode->m = j;
//        newcode->num = i;
//        return;
//    }
//    SL *cur = plist;
//    while(cur->next != plist)
//    {
//        cur = cur->next;
//    }
//    cur->next = newcode;
//    newcode->next = plist;
//    newcode->m = j;
//    newcode->num = i;
//}
//int IsM(SL *plist, int m)
//{
//    SL* one = plist->next;
//    while(one->next != plist)
//    {
//        SL* cur = plist->next;
//        while(cur->next != plist)
//        {
//            SL* next = cur->next;
//            if(next->m == m)
//            {
//                cur->next = next->next;
//                free(next);
//            }
//            cur = cur->next;
//        }
//        cur = plist->next;
//        int j = 0;
//        while(cur->next != plist)
//        {
//            j++;
//            if(j > m)
//            {
//                j = 1;
//            }
//            cur->m = j;
//        }
//    }
//    return plist->next->num;
//}
//int main()
//{
//    int n = 0;
//    int m = 0;
//    scanf("%d %d",&n, &m);
//    SL list;
//    Init(&list);
//    int j = 0;
//    for (int i = 1; i <= n; i++)
//    {
//        j++;
//        if(j > m)
//        {
//            j = 1;
//        }
//        SLPush(&list, i, j);
//    }
//    int last = IsM(&list, m);
//    printf("%d\n",last);
//    return 0;
//}
//#include <stdio.h>
//#include <stdlib.h>
//typedef struct List
//{
//    struct List* next;
//    int num;
//    int m;
//}SL;
//void Init(SL* plist)
//{
//    plist->next = plist;
//    plist->num = 1;
//    plist->m = 0;
//}
//void SLPush(SL* plist, int i)
//{
//    SL *newcode = (SL*)malloc(sizeof(SL));
//    if(plist->next == plist)
//    {
//        plist->next = newcode;
//        newcode->next = plist;
//        newcode->m = 0;
//        newcode->num = i;
//        return;
//    }
//    SL *cur = plist;
//    while(cur->next != plist)
//    {
//        cur = cur->next;
//    }
//    cur->next = newcode;
//    newcode->next = plist;
//    newcode->m = 0;
//    newcode->num = i;
//}
//
//int IsM(SL *plist, int n, int m)
//{
//    if(plist->next == plist)
//        return 1;
//    if(m == 1)
//        return n;
//    plist->m = 1;
//    SL* cur = plist;
//    SL* next = cur->next;
//    int i = 1;
//    while(cur != next)
//    {
//        if(++i > m)
//        {
//            i = 1;
//        }
//        next->m = i;
//        if(next->m == m)
//        {
//            cur->next = next->next;
//            free(next);
//            next = cur->next;
//        }
//        else
//        {
//            cur = next;
//            next = cur->next;
//        }
//    }
//    return cur->num;
//}
//int main()
//{
//    int n = 0;
//    int m = 0;
//    scanf("%d %d",&n, &m);
//    SL *list = (SL*) malloc(sizeof(SL));
//    Init(list);
//
//    for (int i = 2; i <= n; i++)
//    {
//        SLPush(list, i);
//    }
//    int last = IsM(list, n, m);
//    printf("%d\n",last);
//    return 0;
//}
//#include "code.h"
//int main()
//{
//
//    return 0;
//}
//#include <iostream>
//using namespace std;
//class Date
//{
//public:
//    Date(int year, int month, int day)
//        : _year(year)
//        , _month(month)
//        , _day(day)
//    {
//        cout << "Date()" << endl;
//    }
//    Date(const Date& date)
//    {
//        cout << "Date(const Date& date)" << endl;
//    }
//    static int GetNum()
//    {
//        return _num;
//    }
//    int _year;
//    int _month;
//    int _day;
//    static int _num;
//};
//int Date::_num = 0;
//int main()
//{
//    return 0;
//}
//#include "test.h"
//using namespace std;
//class Date
//{
//public:
//    Date()
//    {
//        cout << "Date()" << endl;
//    }
//    Date(const Date& date)
//    {
//        cout << "Date(const Date& date)" << endl;
//    }
//private:
//    int _year;
//    int _month;
//    int _day;
//};
//Date func()
//{
//    Date date;
//    Date date2 = date;
//    Date date3 = date2;
//    return date;
//}
//int main()
//{
//    char *p = new char[1024 * 1024 * 1024];
//    cout << (void*)p << endl;
//
//    return 0;
//}
//#include <iostream>
//using namespace std;
//class Solution
//{
//public:
//    void Convert(string date1)
//    {
//        int i = 0;
//        basic_string<char> ch = date1;
//
//        int a = 3;
//        int b = 2;
//        int c = 2;
//        while(*ch)
//        {
//            ++i;
//            if(i < 5)
//            {
//                _year += *ch * pow(10, a);
//                --a;
//            }
//            else if(i > 5 && i < 8)
//            {
//                _month = *ch * pow(10, b);
//                --b;
//            }
//            else
//            {
//                _day = *ch * pow(10, c);
//                --c;
//            }
//        }
//    }
//    int daysBetweenDates(string date1, string date2)
//    {
//        Convert(date1);
//        Convert(date2);
//
//    }
//private:
//    int _year;
//    int _month;
//    int _day;
//};
//int main()
//{
//    return 0;
////}
//int main()
//{
//    char *p = new char[100];
//    delete []p;
//    return 0;
//}
//#include <iostream>
//class A
//{
//public:
//    A(int a = 0)
//        : _a(a)
//    {}
//private:
//    int _a;
//};
//int main()
//{
//    A *a = (A*)malloc(sizeof(A));
//    a -> A(3);
//    return 0;
//}
//#include <iostream>
//template <typename T>
//void Swap(T& a, T& b)
//{
//    T c = a;
//    a = b;
//    b = c;
//}
//int main()
//{
//    int a = 0;
//    int b = 3;
//    Swap(a, b);
//    return 0;
//}
//#include <iostream>
//using namespace std;
//void operator
//int main()
//{
//    return 0;
//}
//#include <iostream>
//using namespace std;
//int main()
//{
//    //开辟一个整型的空间，没有初始化
//    int *a = new int;
//    //开辟一个double类型的空间，并且初始化
//    double *b = new double(3);
//    //开辟连续5个int类型的空间，没有初始化
//    int *arr1 = new int[5];
//    //开辟连续5个int类型的空间，并初始化
//    int *arr2 = new int[5]{1,2,3,4,5};
//    for (int i = 0; i < 5; ++i)
//    {
//        cout << arr2[i] << ' ';
//    }
//    cout << endl;
//    delete a;
//    delete b;
//    delete [] arr1;
//    delete [] arr2;
//    return 0;
//}
//#include <iostream>
//using namespace std;
//int main()
//{
//    //开辟一个整型的空间，没有初始化
//    int *a = new int;
//    //开辟一个double类型的空间，并且初始化
//    double *b = new double(3);
//    //开辟连续5个int类型的空间，没有初始化
//    int *arr1 = new int[5];
//    //开辟连续5个int类型的空间，并初始化
//    int *arr2 = new int[5]{1,2,3,4,5};
//    for (int i = 0; i < 5; ++i)
//    {
//        cout << arr2[i] << ' ';
//    }
//    cout << endl;
//    delete a;
//    delete b;
//    delete [] arr1;
//    delete [] arr2;
//    return 0;
//}
//#include <iostream>
//using namespace std;
//class Stack
//{
//public:
//    void Init(int capacity)
//    {
//        _a = (int*)malloc(sizeof(int) * capacity);
//        if(_a == nullptr)
//        {
//            perror("malloc fail");
//            exit(-1);
//        }
//        _size = 0;
//        _capacity = capacity;
//    }
//private:
//    int *_a;
//    int _size;
//    int _capacity;
//};
//int main()
//{
//    Stack *st = (Stack*)malloc(sizeof(Stack));
//    int *a = new int;
//    int *b = new int(3);
//    st->Init(4);
//    return 0;
//}
//#include <iostream>
//using namespace std;
//class Stack
//{
//public:
//    Stack(int capacity = 4, int size = 0, int num = 0)
//        : _a(new int[capacity]{0})
//        , _size(size)
//        , _capacity(capacity)
//    {
//        cout << "Stack(int capacity = 4)" << endl;
//    }
//
//private:
//    int *_a;
//    int _size;
//    int _capacity;
//};
//int main()
//{
//    Stack *st = new Stack;
//    return 0;
//}#include <iostream>
//using namespace std;
//class Stack
//{
//public:
//    Stack(int capacity = 4, int size = 0, int num = 0)
//        : _a(new int[capacity]{0})
//        , _size(size)
//        , _capacity(capacity)
//    {
//        cout << "Stack(int capacity = 4)" << endl;
//    }
//
//private:
//    int *_a;
//    int _size;
//    int _capacity;
//};
//int main()
//{
//    Stack *st = new Stack;
//    return 0;
//}
//#include <iostream>
//using namespace std;
//class A
//{
//public:
//    A()
//    {
//        cout << "A()" << endl;
//    }
////    ~A()
////    {
////        cout << "~A()" << endl;
////    }
//};
//int main()
//{
//    A *a = new A[5];
//    delete a;
//    return 0;
//}
//#include <iostream>
//using namespace std;
//class Stack
//{
//public:
//    Stack(int capacity = 4, int size = 0, int num = 0)
//            : _a(new int[capacity]{0})
//            , _size(size)
//            , _capacity(capacity)
//    {
//        cout << "Stack(int capacity = 4)" << endl; //方便观察确实调用了构造函数
//    }
//
//private:
//    int *_a;
//    int _size;
//    int _capacity;
//};
//int main()
//{
//    Stack *st = new Stack[5];
//    delete st;
//    return 0;
//}
//#include <iostream>
//using std::cin;
//using std::cout;
//using std::endl;
//char* Compression(char *fast, char *slow)
//{
//    char *newstr = new char[500];
//
//    char *cur = newstr;
//
//    while(*fast)
//    {
//        int count = 0;
//        while(*fast == *slow)
//        {
//            ++count;
//            ++fast;
//        }
//
//        *cur = *slow;
//        ++cur;
//        *cur = count + 48;
//        ++cur;
//        slow = fast;
//    }
//
//    return newstr;
//}
//int main()
//{
//    char str[500] = "\0";
//    cin >> str;
//    char *newstr = Compression(str, str);
//
//    if(strlen(str) <= strlen(newstr))
//    {
//        cout << "NO" << endl;
//        return 0;
//    }
//
//    cout << newstr << endl;
//    return 0;
//}
//#include <iostream>
//using namespace std;
//int main()
//{
//    char str[10] = "\0";
//    fgets(str, 10, stdin);
//    char *cur = str;
//    int count = 0;
//    while(*cur)
//    {
//        if(*cur == ' ' || *cur == '\n');
//        else
//        {
//            ++count;
//        }
//        ++cur;
//    }
//    cout << count << endl;
//    return 0;
//}
//#include <iostream>
//using namespace std;
//
//template<class T, class Y>
//T Add(const T& a,const Y& b)
//{
//    return a + b;
//}
//int main()
//{
//    cout << Add(1,2.2) << endl;
//    cout << Add('s', 3.2) << endl;
//    return 0;
//}
//#include <iostream>
//using namespace std;
//template<class T>
//class Sqt
//{
//public:
//    Sqt(int capacity = 4)
//        : _a(new T[capacity])
//        , _size(0)
//        , _capacity(capacity)
//    {}
//    ~Sqt()
//    {
//        if(_a != nullptr)
//        {
//            delete []_a;
//        }
//        _a = nullptr;
//        _size = _capacity = 0;
//    }
//private:
//    T *_a;
//    int _size;
//    int _capacity;
//};
//int main()
//{
//    Sqt<int> sqi;
//    Sqt<double> sqd;
//    return 0;
//}
//#include <iostream>
//using namespace std;
//class A
//{
//public:
//    A()
//    {
//        cout << "A()" << endl;
//    }
//    A(const A& a)
//    {
//        cout << "A(const A& a)" << endl;
//    }
//    A& operator=(const A& another)
//    {
//        cout << "A& operator=(const A& another)" << endl;
//        return *this;
//    }
//    ~A()
//    {
//        cout << "~A()" << endl;
//    }
//private:
//    int _a;
//};
//int main()
//{
//    A a1;
//    A a3;
//    A a2 = a1;
//    a3 = a1;
//    return 0;
//}
//#include <iostream>
//using namespace std;
//void Swap(int& a, int& b)
//{
//    int tmp = a;
//    a = b;
//    b = tmp;
//}
//void Swap(double& a, double& b)
//{
//    double tmp = a;
//    a = b;
//    b = tmp;
//}
//void Swap(char& a, char& b)
//{
//    char tmp = a;
//    a = b;
//    b = tmp;
//}
//
//int main()
//{
//    return 0;
//}
//#include <iostream>
//using namespace std;
//template<class T>
//T GetNum(int n)
//{
//    T b = n;
//    return b;
//}
//int main()
//{
//    int a = 3;
//    int b = 4;
//    int c = GetNum<int>(a);
//    return 0;
//}
//#include <iostream>
//using namespace std;
//template<class T, class Y>
//Y Add(const T& a, const Y& b)
//{
//    return a + b;
//}
//int main()
//{
//    int a = 3;
//    double b = 4.7;
//    cout << Add(a, b) << endl;
//    return 0;
//#include <iostream>
//using namespace std;
//
//template <class T>
//class Stack
//{
//public:
//    Stack(int capacity = 4)
//            : _a(new T[capacity])
//            , _size(0)
//            , _capacity(capacity)
//    {}
//    ~Stack();
//private:
//    T *_a;
//    int _size;
//    int _capacity;
//};
//
//template<class T>
//Stack<T>::~Stack()
//{
//    delete []_a;
//    _a = nullptr;
//    _size = _capacity = 0;
//}
//
//int main()
//{
//    Stack<int> st;
//    return 0;
//}
//#include <iostream>
////void Print()
////{
////    void Swap()
////    {
////        ;
////    }
////}
//int main() {
//    char c1,c2;
//    int a1,a2;
//    c1 = getchar();
//    scanf("%2d",&a1);
//    c2 = getchar();
//    scanf("%3d",&a2);
//    printf ("%d,%d,%c,%c\n",a1,a2,c1,c2);
//}
//#include <iostream>
////void Print()
////{
////    void Swap()
////    {
////        ;
////    }
////}
//using namespace std;
//int main()
//{
//    int a = 3;
//
//    int *pa = &a;
//    int& b = a;
//
//
//    return 0;
//}
//#include <iostream>
//#include <string>
//using namespace std;
//int main()
//{
//    string s1;
//    string s2("hello world");
////    string s3 = "hello world";
////    string s4(s2);
////    string s5(4, 'x');
////    string s6({'y', 'x', 'y'});
////    cout << s1 << endl;
////    cout << s2 << endl;
////    cout << s3 << endl;
////    cout << s4 << endl;
////    cout << s5 << endl;
////    cout << s6 << endl;
////    cout << size(s1) << endl;
////    cout << size(s2) << endl;
////    cout << size(s3) << endl;
////    cout << size(s4) << endl;
////    cout << size(s5) << endl;
////    cout << size(s6) << endl;
////    cout << s2.capacity() << endl;
////    cout << s2.size() << endl;
////    cout << s1.empty() << endl;
////    cout << s2.empty() << endl;
//    return 0;
//}
//#include <iostream>
//#include <string>
//using namespace std;
//int main()
//{
////    string s1;
//    string s2("hello");
//    cout << s2.size() << endl;
//    s2.resize(3);
//    cout << s2.size() << endl;
//    cout << s2 << endl;
////    s2.reserve(100);
////    string s3 = "hello world";
////    string s4(s2);
////    string s5(4, 'x');
////    string s6({'y', 'x', 'y'});
////    s2.clear();
////    cout << s1 << endl;
////    cout << s2 << endl;
////    if(s1.empty())
////        cout << "s1" << endl;
////    if(s2.empty())
////        cout << "s2" << endl;
////    cout << s1.empty() << endl;
//    cout << s2.capacity() << endl;
//    return 0;
//}
//#include <iostream>
//using namespace std;
//class String
//{
//public:
//    String()
//
//    {}
//private:
//    char *_str;
//};
//int main()
//{
//
//    return 0;
//}
/**
 * class Solution
{
public:
    int firstUniqChar(string s)
    {
        int size = s.size();
        int i = 0;
        while(size--)
        {
            string::iterator str = s.begin() + i;
            string::iterator begin = s.begin();
            string::iterator end = s.end();
            int flag = 0;
            while(begin < end)
            {
                if(str != begin && *str == *begin)
                {
                    flag = 1;
                    break;
                }
                ++begin;
            }
            if(flag == 0)
                return i;
            ++i;
        }
        return -1;
    }
};
 #include <cmath>
#include <iterator>
class Solution
{
public:
    int StrToInt(string str)
    {
        string::iterator it = str.begin();
        if(*it == '+' || *it == '-' || (*it >=48 && *it <= 57))
        {
            ++it;
            while(it != str.end())
            {
                if(*it < 48 || *it > 57)
                    return 0;
                it++;
            }
        }
        else
            return 0;

        int sum = 0;
        int i = 0;
        it = str.end() - 1;
        while(it != str.begin())
        {
            sum = sum + (*it-48) * pow(10, i);
            ++i;
            --it;
        }
        if(*it == '-')
            return -1*sum;
        else if(*it == '+')
            return sum;
        else
        {
            sum = sum + (*it-48) * pow(10, i);
            return sum;
        }
    }
    class Solution
{
public:
    void Swap(char& str1, char& str2)
    {
        char tmp = str1;
        str1 = str2;
        str2 = tmp;
    }
    void reverseString(vector<char>& s)
    {
        vector<char>::iterator begin = s.begin();
        vector<char>::iterator end  =s.end() - 1;
        while(begin < end)
        {
            Swap(*begin, *end);
            ++begin;
            --end;
        }
    }
 */
//#include <iostream>
//using namespace std;
//template<class T, int A>
//int Swap()
//{
//    return A;
//}
//int main()
//{
//    cout << Swap<int ,10>() << endl;
//    return 0;
//}
///**
// * class Solution {
//public:
//    string reverseOnlyLetters(string s)
//    {
//        string::iterator begin = s.begin();
//        string::iterator end = s.end() - 1;
//        while(begin < end)
//        {
//            while(begin < end && (*begin < 'A' || (*begin > 'Z' && *begin < 'a') || *begin > 'z'))
//                ++begin;
//            while(begin < end && (*end <'A' || (*end > 'Z' && *end < 'a') || *end > 'z'))
//                --end;
//            swap(*begin, *end);
//            ++begin;
//            --end;
//        }
//        return s;
//    }
//};
//#include <iostream>
//#include <string>
//using namespace std;
//class Count
//{
//public:
//
//private:
//
//};
//    int firstUniqChar(string s)
//    {
//        int arr[256] = {0};
//        string::iterator begin = s.begin();
//        while(begin < s.end())
//        {
//            ++arr[*begin];
//            ++begin;
//        }
//        begin = s.begin();
//        for(int i = 0; begin + i < s.end(); i++)
//        {
//            if(arr[*(begin + i)] == 1)
//                return i;
//        }
//        return -1;
//    }
//int main()
//{
//    string s = "leetcode";
//    cout << firstUniqChar(s) << endl;
//    return 0;
//}
//#include <stdio.h>
//#include <stdlib.h>
//
//int main()
//{
//   int arr[] = {0,1,3,6,10,15,21,28,36,45};
//    int sum = 0;
//    for(int i = 100; i < 1000; i++)
//    {
//        int x = i;
//        while(x)
//        {
//            sum += arr[x%10];
//            x /= 10;
//        }
//        if(i == sum)
//            printf("%d\n", i);
//    }
//    return 0;
//}
//
//#include <stdio.h>
//#include <stdlib.h>
//
//int main()
//{
//    int arr[] = {0,1,3,6,10,15,21,28,36,45};
//    int sum = 0;
//    for(int i = 100; i < 1000; i++)
//    {
//        int x = i;
//        while(x)
//        {
//            sum += arr[x%10];
//            x /= 10;
//        }
//        if(i == sum)
//            printf("%d\n", i);
//    }
//    return 0;
//}
//#include <iostream>
//#include <string>
//using namespace std;
//int main()
//{
//    string str;
//    str.reserve(20);
//    cout << str.capacity() << endl;
//    str.reserve(10);
//    cout << str.capacity() << endl;
//
//    return 0;
////}
//#include <iostream>
//using namespace std;
//int main()
//{
//    int arr[10] = {0};
//    scanf("%d",&arr);
//    for(auto e : arr)
//    {
//        cout << e << ' ';
//    }
//    cout << endl;
//    return 0;
//}
//}
//#include <iostream>
//#include <string>
//using namespace std;
//string addStrings(string num1, string num2)
//{
//    string big = num1;
//    string small = num2;
//    string::iterator bigend = big.end() - 1;
//    string::iterator smallend = small.end() - 1;
//    if(big.size() < small.size())
//    {
//        big = num2;
//        small = num1;
//        bigend = big.end() - 1;
//        smallend = small.end() - 1;
//    }
//
//    while(smallend >= small.begin())
//    {
//        int smallnum = *smallend - '0';
//        int bignum = *bigend - '0';
//        int sum = smallnum + bignum;
//        if(sum >= 10)
//        {
//            if(bigend == big.begin())
//            {
//                sum %= 10;
//                *bigend = sum + '0';
//                big.insert(big.begin(),'1');
//            }
//            else
//            {
//                ++(*(bigend-1));
//                sum %= 10;
//                *bigend = sum + '0';
//            }
//
//        }
//        else
//        {
//            *bigend = sum + '0';
//        }
//        --smallend;
//        --bigend;
//    }
//    while(bigend >= big.begin())
//    {
//        int bignum = *bigend - '0';
//        if(bigend == big.begin())
//        {
//            if(bignum >= 10)
//            {
//                bignum %= 10;
//                *bigend = bignum + '0';
//                big.insert(big.begin(),'1');
//            }
//            else;
//        }
//        else
//        {
//            if(bignum >= 10)
//            {
//                ++(*(bigend-1));
//                bignum %= 10;
//                *bigend = bignum + '0';
//            }
//            else;
//        }
//        --bigend;
//    }
//    return big;
//}
//int main()
//{
//    string s1 = "1";
//    string s2 = "9";
//    string s3 = addStrings(s1, s2);
//    cout << s3 << endl;
//    return 0;
//}
//#include <iostream>
//using namespace std;
//#include <stdio.h>
//union a
//{
//
//};
//int main()
//{
//    printf("%d\n", sizeof(void));
//    return 0;
//}
//#include <iostream>
//#include <string>
//using namespace std;
//int main()
//{
//    string s1;
//    string s2("hello world");
//    string s4 = s2;
//    string s3(s2);
//    cout << s4 << endl;
//    cout << s3 << endl;
//    string s5 = "hello world";
//    cout << s5 << endl;

//    string s5 = 'x';
//    string s6;
//    s6 = 'x';
//    cout << s6 << endl;
//    string s7 = "hello world";
//    string s8(s7, 0, 3);
//    cout << s8 << endl;
//    string s9("hello world", 4);
//    cout << s9;
//    string s10(10, 'x');
//    cout << s10;
//    string s11 = "hello world";
//    string s12(s11.begin(), s11.end()-1);
//    cout << s12;
//    int len = s1.size();
//    cout << len << endl;
//    cout << s1.capacity() << endl;
//    string s1 = "hello world";
//    cout << s1.empty() << endl;
//    string s2;
//    cout << s2.empty() << endl;
//    string s3 = "hello world";
//    cout << "清空之前的容量：" << s3.capacity() << endl;
//    cout << "清空之前的长度：" <<s3.size() << endl;
//
//    s3.clear();
//    cout << "清空之后的容量：" << s3.capacity() << endl;
//    cout << "清空之后的长度：" <<s3.size() << endl;
//    string s4 = "hello world";
//    cout << "缩容之前的容量：" << s4.capacity() << endl;
//    s4.reserve(2);
//    cout << "缩容之后的容量：" << s4.capacity() << endl;

//    string s5 = "hello world";
//    cout << s5 << endl;
//    cout << "调整有效字符之前的容量：" << s5.capacity() << endl;
//    cout << "调整有效字符之前的长度：" <<s5.size() << endl;
//
//    s5.resize(30, 'x');
//    cout << s5 << endl;
//    cout << "调整有效字符之后的容量：" << s5.capacity() << endl;
//    cout << "调整有效字符之后的长度：" <<s5.size() << endl;
//    cout << s1[0] << endl;
//    string::reverse_iterator  rb = s1.rbegin();
//    string::reverse_iterator re = s1.rend();
//    while(re >= rb)
//    {
//        cout << *re << ' ';
//        --re;
//    }
//    for(auto e : s1)
//    {
//        cout << e << ' ';
//    }
//    cout << endl;
//    string s1 = "hello world";
//    cout << s1 << endl;
//    s1 += " hello CSDN";
//    cout << s1 << endl;
//    string s1;
//    getline(cin, s1);
//    cout << s1 << endl;
//    return 0;
//
//}
//#include <iostream>
//#include <string>
//using namespace std;
//int main()
//{
//    string s1("Test.cpp.cpppp");
//    int pos = s1.rfind('.');
//    if(pos != string::npos)
//    {
//        cout << s1.substr(pos, s1.size() - pos) << endl;
//    }
//    return 0;
//}
//#include <iostream>
//using namespace std;
//namespace wyd
//{
//    class string
//    {
//    public:
//        string(const char *str)
//            : _num(strlen(str))
//            , _str(new char[_num + 1])
//            , _size(_num)
//            , _capacity(_num)
//        {
//            strcpy(_str, str);
//        }
//    private:
//        size_t _num;
//        char *_str;
//        size_t _size;
//        size_t _capacity;
//    };
//}
//int main()
//{
//    wyd::string s("hello world");
//    return 0;
//}
//#include <iostream>
//#include <string>
//using namespace std;
//int main()
//{
////    string s2 = "CSDN";
////
////    cout << "插入之前：" << s1 << endl;
////    s1.insert(1, s2);
////    cout << "插入之后：" << s1 << endl;
////    string s1 = "hello world";
////    cout << "删除之前：" << s1 << endl;
////    s1.erase(s1.begin(), s1.end()-1);
////    cout << "删除之后：" << s1 << endl;
//    string s2 = "hello world";
//    size_t n = s2.find('w', 0);
//    string s3 = s2.substr(n,s2.size() - n);
//    if(s2 < s3)
//        cout << s2;
//    else
//        cout << s3;
//    return 0;
////}
//#include <iostream>
//using namespace std;
//int main()
//{
////    float a = 1.1;
////    double b = 2.2;
////    printf("%f\n", a);
////    printf("%lf\n", b);
////    printf("%lf\n", a+b);
//
//    size_t c = 1;
//    unsigned d = 1;
//    printf("%zu\n", c);
//    printf("%u\n", d);
//    return 0;
//}
//#include <stdio.h>
//int main()
//{
//    int b;
//    printf("helloworld %n12345\n", &b);
//    printf("%d\n", b);
//    return 0;
//}
//#include <iostream>
//using namespace std;
//int main()
//{
//
//    string a="hello world";
//    string b=a;
//
//    if (a.c_str()==b.c_str())
//        cout<<"true"<<endl;    //true
//    else
//        cout<<"false"<<endl;
//
//    string c=b;
//    c="";
//
//    if (a.c_str()==b.c_str())     //
//        cout<<"true"<<endl;
//    else
//        cout<<"false"<<endl;
//
//    a="";
//
//    if (a.c_str()==b.c_str())
//        cout<<"true"<<endl;
//    else
//        cout<<"false"<<endl;
//
//    return 0;
//}
//int main(int argc, char *argv[])
//{
//    string strText = "How are you?";
//    string strSeparator = " ";
//    string strResult;
//
//    int size_pos = 0;
//    int size_prev_pos = 0;
//    while((size_pos = strText.find_first_of(strSeparator, size_pos)) != string::npos)
//    {
//        strResult = strText.substr(size_prev_pos, size_pos-size_prev_pos);
//        cout<<strResult<<" ";
//        size_prev_pos = ++size_pos;
//    }
//
//    if(size_prev_pos != strText.size())
//    {
//        strResult = strText.substr(size_prev_pos, size_pos-size_prev_pos);
//        cout<<strResult<<" ";
//    }
//
//    cout<<endl;
//    return 0;
//}
//#include <iostream>
//using namespace std;
//class Solution
//{
//public:
//    string reverseStr(string s, int k)
//    {
//        if(s.size() < k)
//        {
//            reverse(s.begin(), s.end()-1);
//            return s;
//        }
//
//        int count  = 0;
//        string::iterator cur = s.begin();
//        while(cur < s.end())
//        {
//            ++count;
//            int remaining = s.size - count;
//            if(remaining < k)
//            {
//                reverse(s.begin() + count, s.end());
//                return s;
//            }
//            else if(remaining >= k && remaining < 2k)
//            {
//                reverse(s.begin(), s.begin() + k);
//            }
//            else;
//            ++cur;
//        }
//
//        return s;
//    }
//};
//string reverseStr(string s, int k)
//{
//    // if(s.size() < k)
//    // {
//    //     reverse(s.begin(), s.end()-1);
//    //     return s;
//    // }
//
//    int count  = 0;
//    string::iterator cur = s.begin();
//    while(cur < s.end())
//    {
//        ++count;
//        int remaining = s.size() - count;
//        if(remaining < k)
//        {
//            reverse(s.begin() + count, s.end());
//            return s;
//        }
//        else if(remaining >= k && remaining < 2 * k)
//        {
//            reverse(s.begin() + count, s.begin() + count + k);
//        }
//        else;
//        if(count % (2 * k) == 0)
//        {
//            int num = 0;
//            if(count != 2*k)
//                num = count;
//            reverse(s.begin() + num, s.begin() + num + k);
//        }
//        else;
//
//        ++cur;
//    }
//
//    return s;
////}
//string reverseStr(string s, int k)
//{
//    // if(s.size() < k)
//    // {
//    //     reverse(s.begin(), s.end()-1);
//    //     return s;
//    // }
//
//    int count  = 0;
//    while(count < s.size())
//    {
//        int rem = s.size() - count;
//        if(rem < k)
//        {
//            reverse(s.begin()+s.size()-count, s.end());
//        }
//        else if(rem >= k && rem < 2*k)
//        {
//            reverse(s.begin()+s.size()-count, s.begin()+s.size()-count+k);
//        }
//        if(count != 0 && count % 2 * k == 0)
//        {
//            int num = count - 2*k;
//            reverse(s.begin()+num, s.begin()+num+k);
//        }
//        count += 2*k;
//
//    }
//
//    return s;
//}
//#pragma pack(2)
//class A
//{
//    int i;
//    union U
//    {
//        char str[13];
//        int i;
//    }u;
//    void func() {};
//    typedef char* cp;
//    enum
//    {
//        red,
//        green,
//        blue
//    }color;
//};
//enum
//{
//    a,
//    b
//}A;
//int main()
//{
////    scanf("");
////    cout << sizeof(A) << endl;
//    int arr[3] = {1,2,3};
//    cout << *(arr) << endl;
//    return 0;
//}
//struct A
//{
//    int a:16;
//}a;
//int main()
//{
//
//    cout << sizeof(A) << endl;
//    cout << a.a << endl;
//}
//#include <stdio.h>
//struct T
//{
//    char a;
//    int *d;
//    int b;
//    int c:16;
//    double e;
//};
//struct S
//{
//    char a:3;
//    char b:4;
//    char c:5;
//    char d:4;
//};
//int main()
//{
//    struct S s = {0};
//    s.a = 10;
//    s.b = 12;
//    s.c = 3;
//    s.d = 4;
////    printf("%lu\n", sizeof(s));
//    printf("%d %d %d %d\n",s.a, s.b, s.c, s.d);
//    1/010
//    /1100
//    /00011
//    /0100
//    return 0;
//}

//int main()
//{
//    string num1 = "123";
//    string num2 = "456";
//    cout << multiply(num1, num2) << endl;
//    return 0;
//}
//#include <stdio.h>
//int main()
//{
//    float a = 0;
//    int b = 0;
//    char c = '1';
//    scanf(" %c", &c);
//    printf("c=%c\n", c);
//}
//#include <iostream>
//#include <string>
//using namespace std;
//string addStrings(string num1, string num2)
//{
//    string big = num1;
//    string small = num2;
//    string::iterator bigend = big.end() - 1;
//    string::iterator smallend = small.end() - 1;
//    if(big.size() < small.size())
//    {
//        big = num2;
//        small = num1;
//        bigend = big.end() - 1;
//        smallend = small.end() - 1;
//    }
//
//    int next = 0;
//    while(smallend >= small.begin() || bigend >= big.begin())
//    {
//        int smallnum = 0;
//        int bignum = 0;
//
//        if(smallend >= small.begin())
//            smallnum = *(smallend--) - '0';
//        if(bigend >= big.begin())
//            bignum = *(bigend--) - '0';
//
//        int sum = smallnum + bignum + next;
//        next = sum / 10;
//        sum %= 10;
//        *(bigend+1) = sum + '0';
//
//    }
//    if(next == 1)
//    {
//        big.insert(big.begin(), '1');
//    }
//    return big;
//}
//string multiply(string num1, string num2)
//{
//    string big = num1;
//    string small = num2;
//    if(num1.size() < num2.size())
//    {
//        big = num2;
//        small = num1;
//    }
//    string::iterator bend = big.end() - 1;
//    string add1;
//    string add2 = "0";
//    int bcount = 0;
//    while(bend >= big.begin())
//    {
//        string::iterator send = small.end() - 1;
//        int scount = 0;
//        while(send >= small.begin())
//        {
//            int num = (*bend-'0')*(*send-'0');
//            if(num == 0)
//            {
//                add1 += '0';
//            }
//            while(num > 0)
//            {
//                add1 += num % 10 + '0';
//                num /= 10;
//            }
//            reverse(add1.begin(), add1.end());
//            string zeronum(scount+bcount, '0');
//            add1 += zeronum;
//            add2 = addStrings(add1, add2);
//            add1 = "\0";
//            --send;
//            ++scount;
//        }
//        --bend;
//        ++bcount;
//    }
//    return add2;
//}
//int main()
//{
//    string num1 = "9";
//    string num2 = "9";
//    cout << multiply(num1, num2) << endl;
//    return 0;
//}
/**
 * class Solution
{
public:
    bool isPalindrome(string s)
    {
        string copy;
        for(auto e : s)
        {
            if((e >= '0' && e <= '9') || (e >= 'a' && e <= 'z'))
            {
                copy += e;
            }
            else if(e >= 'A' && e <= 'Z')
            {
                copy += e + 'a' - 'A';
            }
            else;
        }
        string::iterator begin = copy.begin();
        string::iterator end = copy.end() - 1;
        while(begin < end)
        {
            if(*begin != *end)
            {
                return false;
            }
            ++begin;
            --end;
        }
        return true;
    }
    class Solution
{
public:
    string reverseWords(string s)
    {
        string::iterator cur = s.begin();
        string::iterator next = s.begin();
        while(next <= s.end())
        {
            if(*next == ' ' || next == s.end())
            {
                string::iterator right = next - 1;
                string::iterator left = cur;
                while(left < right)
                {
                    swap(*left, *right);
                    ++left;
                    --right;
                }
                cur = next + 1;
            }
            ++next;
        }
        return s;
    }

};

 */

//#include "test.h"
//void Test1()
//{
//    bit::string s1("hello world");
//    bit::string s2("hello Linux!123456");
//    s1.swap(s2);
//    s1 += "12345678910111213141516";
//    s2.resize(5,'w');
//    bit::string s3;
//    s1 = s2;
//    s1 += 'l';
//    s1 += 'l';
//    s1 += 'l';
//    s1 += 'l';
//    s1 += 'l';
//    s1 += 'l';
//    s1 += 'l';
//    s1 += 'l';
//    s1 += 'l';
//    s1 += 'l';
//    s1 += 'l';
//    s1 += 'l';
//    s1[0] = 48;
//    cout << s1 << endl;
//    cout << s2  << endl;

//}
//void Test2()
//{
//    bit::string s1("hello ");
////    bit::string s2("world");
//    s1 += "world";
////    s1 += 'c';
//    cout << s1.size() << endl;
//    cout << s1.capacity() << endl;
//    s1.clear();
//    cout << s1.size() << endl;
//    cout << s1.capacity() << endl;
//    cout << s1;
//
//}
//void Test3()
//{
//    bit::string s1 = "helloworld";
//    bit::string::iterator begin = s1.begin();
//    while(begin < s1.end())
//    {
//        cout << *(begin++) << ' ';
//    }
//    cout << endl;
//    for(auto e: s1)
//    {
//        cout << e << ' ';
//    }
//    cout << endl;
//}
//void Test4()
//{
//    bit::string s1 = "hello";
//    bit::string s2 = "lalalala";
//    cout << s1 << endl << s2 << endl;
//    s1.swap(s2);
//    cout << s1 << endl << s2 << endl;
//}
//void Test5()
//{
//    string str("https://legacy.cplusplus.com/reference/string/string/substr/");
//	string sub1, sub2, sub3;
//	size_t pos1 = str.find(':');
//	sub1 = str.substr(0, pos1 - 0);
//	cout << sub1 << endl;
//
//	size_t pos2 = str.find('/', pos1+3);
//	sub2 = str.substr(pos1 + 3, pos2 - (pos1 + 3));
//	cout << sub2 << endl;
//
//	sub3 = str.substr(pos2 + 1);
//	cout << sub3 << endl;
//    bit::string s1 = "hellololoo";
//    bit::string s2 = "ll";
////    swap(s1, s2);
//    bit::string half = s1.substr(1);
//    cout << half << endl;
////    cout << s1.find("lo", 4) << endl;
////    s1.erase(1);
////    cout << s1 << endl;
//}
//void Test6()
//{
//
//}
//int main()
//{
////    Test1();//测试构造
////    Test2(); //测试尾插
////    Test3();//测试迭代器
////    Test4(); //测试交换函数
//    Test5();
//    return 0;
//}
//#include <stdio.h>
//int main()
//{
//    int arr[] = {1,2,3,4,5};
//    short *p = (short*)arr;
//    int i = 0;
//    for(i=0; i<4; i++)
//    {
//        *(p+i) = 0;
//    }
//
//    for(i=0; i<5; i++)
//    {
//        printf("%d ", arr[i]);
//    }
//    return 0;
//}
//#include "test.h"
//size_t bit::string::npos = -1;
//bit::string::string(const char *str)
//{
//    _size = _capacity = strlen(str);
//    _str = new char[_capacity + 1];
//    strcpy(_str, str);
//}
//bit::string::string(const bit::string& s)
//{
//    _size = s._size;
//    _capacity = s._capacity;
//    _str = new char[_capacity + 1];
//    strcpy(_str, s._str);
//}
//bit::string::~string()
//{
//    if(_str != nullptr)
//    {
//        delete []_str;
//        _str = nullptr;
//        _size = _capacity = 0;
//    }
//}
//bit::string& bit::string::operator=(const bit::string& s)
//{
//    if(this != &s)
//    {
//        char *tmp = new char[s._capacity + 1];
//        strcpy(tmp, s._str);
//        delete []_str;
//
//        _str = tmp;
//        _size = s._size;
//        _capacity = s._capacity;
//    }
//    return *this;
//}
//
//bit::string::iterator bit::string::begin()
//{
//    return _str;
//}
//
//bit::string::iterator bit::string::end()
//{
//    return _str + _size;
//}
//
//size_t bit::string::size() const
//{
//    return _size;
//}
//
//size_t bit::string::capacity() const
//{
//    return _capacity;
//}
//
//bool bit::string::empty() const
//{
//    return _size == 0;
//}
//
//void bit::string::reserve(size_t n)  //只扩容不缩容
//{
//    if(n > _capacity)
//    {
//        _capacity = n;
//        char *newstr = new char[_capacity + 1];
//        strcpy(newstr, _str);
//        delete []_str;
//        _str = newstr;
//    }
//}
//
//void bit::string::resize(size_t n, char c)
//{
//    if(n > _size)
//    {
//        if(n > _capacity)
//            reserve(n);
//        for (size_t i = _size; i < n; ++i)
//        {
//            _str[i] = c;
//        }
//        _str[n] = '\0';
//    }
//    _size = n;
//}
//
//ostream& bit::operator<<(std::ostream &out, const bit::string &s)
//{
//    for(int i = 0; i < s.size(); ++i)
//    {
//        out << s._str[i];
//    }
//    return out;
//}
//
//void bit::string::clear()
//{
//    _size = 0;
//}
//
//void bit::string::push_back(char c)
//{
//    if(_size == _capacity)
//        resize(_size+1, c);
//    else
//        _str[_size++] = c;
//}
//
//bit::string& bit::string::operator+=(char c)
//{
//    push_back(c);
//    return *this;
//}
//
//const char *bit::string::c_str() const
//{
//    return _str;
//}
//
//void bit::string::append(const char *str)
//{
//    reserve(_capacity+ strlen(str));
//    strcpy(_str+_size, str);
//    _size += strlen(str);
//}
//
//bit::string &bit::string::operator+=(const char *str)
//{
//    append(str);
//    return *this;
//}
//
//void bit::string::swap(bit::string& s)
//{
//    std::swap(_str, s._str);
//    std::swap(_size, s._size);
//    std::swap(_capacity, s._capacity);
//}
//
//char& bit::string::operator[](size_t index)
//{
//    assert(index < _size);
//    return _str[index];
//}
//
//const char& bit::string::operator[](size_t index) const
//{
//    assert(index < _size);
//    return _str[index];
//}
//
//bool bit::string::operator<(const bit::string &s)
//{
//    return strcmp(_str, s._str) < 0;
//}
//
//bool bit::string::operator==(const bit::string &s)
//{
//    return strcmp(_str, s._str) == 0;
//}
//
//bool bit::string::operator<=(const bit::string &s)
//{
//    return *this == s || *this < s;
//}
//
//bool bit::string::operator>=(const bit::string &s)
//{
//    return !(*this < s);
//}
//
//bool bit::string::operator>(const bit::string &s)
//{
//    return !(*this <= s);
//}
//
//bool bit::string::operator!=(const bit::string &s)
//{
//    return !(*this == s);
//}
//
//size_t bit::string::find(char c, size_t pos) const
//{
//    assert(pos < _size);
//    for (size_t i = pos; i < _size; ++i)
//    {
//        if(_str[i] == c)
//            return i;
//    }
//    return bit::string::npos;
//}
//
//size_t bit::string::find(const char *s, size_t pos) const
//{
//    size_t i = find(*s, pos);
//    if (i == bit::string::npos)
//        return i;
//    while(i < _size)
//    {
//        size_t k = i + 1;
//        int ret = 0;
//        for (int j = 1; j < strlen(s); ++j)
//        {
//            if(_str[k] != s[j])
//            {
//                ret = 1;
//                break;
//            }
//            ++k;
//            if(k > _size)
//                return -1;
//        }
//        if(ret == 0)
//            return i;
//        else
//            i = find(*s, k);
//    }
//    return bit::string::npos;
//}
//
//bit::string& bit::string::erase(size_t pos, size_t len)
//{
//    assert(pos < _size);
//    if(len == npos || pos + len >= _size)
//    {
//        _size = pos;
//        _str[_size] = '\0';
//        return *this;
//    }
//    while(pos + len < _size)
//    {
//        _str[pos] = _str[pos + len];
//        ++pos;
//    }
//    _size -= len;
//    _str[_size] = '\0';
//    return *this;
//}
//
//bit::string bit::string::substr(size_t pos, size_t len) const
//{
//    assert(pos < _size);
//    if(len == npos || pos + len >= _size)
//    {
//        len = _size - pos;
//    }
//    string sstr;
//    sstr.reserve(len);
//    sstr._size = len;
//    strncpy(sstr._str, _str+pos, len);
//    return sstr;
//}
//#include <iostream>
//#include <cstring>
//#include <cassert>
//using namespace std;
//namespace bit
//{
//    class string
//    {
//    public:
//        typedef char *iterator;
//    public:
//
//        string(const char *str = "");
//        string(const bit::string& s);
//        string& operator=(const bit::string& s);
//        ~string();
//
//        iterator begin();
//        iterator end();
//
//        void push_back(char c);
//        string &operator+=(char c);
//        void append(const char *str);
//        string& operator+=(const char *str);
//        void clear();
//        void swap(string &s);
//        const char *c_str() const;
//
//        size_t size() const;
//        size_t capacity() const;
//        bool empty() const;
//        void resize(size_t n, char c = '\0');
//        void reserve(size_t n);
//
//        char& operator[](size_t index);
//        const char& operator[](size_t index) const;
//
//        bool operator<(const string &s);
//        bool operator<=(const string &s);
//        bool operator>(const string &s);
//        bool operator>=(const string &s);
//        bool operator==(const string &s);
//        bool operator!=(const string &s);
//
//////         返回c在string中第一次出现的位置
//        size_t find(char c, size_t pos = 0) const;
//
//////         返回子串s在string中第一次出现的位置
//        size_t find(const char *s, size_t pos = 0) const;
//
//////         在pos位置上插入字符c/字符串str，并返回该字符的位置
////        string &insert(size_t pos, char c);
////        string &insert(size_t pos, const char *str);
//
//////         向后删除pos位置的len个字符
//        string& erase(size_t pos, size_t len = npos);
//        string substr (size_t pos = 0, size_t len = npos) const;
//    private:
//        char *_str;
//        size_t _capacity;
//        size_t _size;
//        static size_t npos;
//        friend ostream& operator<<(ostream& out, const bit::string& s);
//    };
//}
//#include <stdio.h>
//int main()
//{
//    int arr[2][3] = {{1, 2, 3}, {4, 5, 6}};
//    printf("%d\n", **(arr + 1));
//    return 0;
//}
//#include<stdio.h>
//int Checkss(int m)
//{
//    for(int i = 2;i < m;i++)
//    {
//        if(m % i == 0)
//            return 0;
//    }
//    return m;
//}
//int main()
//{
//    int sum = 0;
//    for(int i = 2;i <= 51;++i)
//    {
//        sum += Checkss(i);
//    }
//    printf("The result is:%d\n",sum);
//}
//#include <stdio.h>
//int main()
//{
//    int c = 699050;
//    printf("%d\n", (short)c);
//    printf("%d\n", c);
//    return 0;
//}
//#include "test.h"
//int main()
//{
//    bit::string s1;
//    bit::string s2;
//    cin >> s1 >> s2;
//    cout << s1 << endl << s2;
//    return 0;
//////}
//#include <stdio.h>
//int main()
//{
//    char a[10] = "\0"; //初始化一下，防止是随机值
//    char b; //删除的字母
//    for(int i = 0; i < 10; i++)
//    {
//        scanf("%c", &a[i]);
//    }
//
//    getchar(); //清理缓冲区
//
//    printf("请输入你要删除的字母: ");
//    scanf("%c", &b);
//    for(int i = 0; i < 10; i++)
//    {
//        if(a[i] != b) //不是删除的字母
//        {
//            printf("%c", a[i]);
//        }
//    }
//    return 0;
//}
//#include <iostream>
//#include <string>
//using namespace std;
//string addBinary(string a, string b)
//{
//    string big = a;
//    string small = b;
//    if(a.size() < b.size())
//    {
//        big = b;
//        small = a;
//    }
//    string result = "0";
//    result += big;
//
//    string::iterator rend = result.end() - 1;
//    string::iterator send = small.end() - 1;
//    while(send >= small.begin())
//    {
//        *rend += *send - '0';
//        if(*rend >= 2 + '0')
//        {
//            ++(*(rend - 1));
//            *rend  = *rend % 2 + '0';
//        }
//        --rend;
//        --send;
//    }
//    while(rend > result.begin())
//    {
//        if(*rend == 2 + '0')
//        {
//            ++(*(rend - 1));
//            *rend  = *rend % 2 + '0';
//        }
//        --rend;
//    }
//    if(*rend == '0')
//    {
//        result.erase(result.begin());
//    }
//    return result;
//}
//int main()
//{
//    string a = "0";
//    string b = "0";
//    string sum = addBinary(a, b);
//    cout << sum << endl;
//    return 0;
////}
//#include <stdio.h>
//int main()
//{
//    int a[3][4] = {{1,3,5,7},
//                   {9,11,13,15},
//                   {17,19,21,23}};
//    int (*p) [4] = &a[0];
//    int q = &a[0];
//    return 0;
////}
//#include <stdio.h>
//int main()
//{
//    int a[2][2] = {1,2,3,4};
//    printf("%d\n", **(a + 1));
//    return 0;
//}
//#include <stdio.h>
//enum A
//{
//
//};
//int main()
///{
//    char c;
//    char *pc = &c;
//    char **ppc = &pc;
//
//    short s;
//    short *ps = &s;
//    short **pps = &ps;
//
//    int i;
//    int *pi = &i;
//    int **ppi = &pi;
//
//    double d;
//    double *pd = &d;
//    double **ppd = &pd;
//
//    float f;
//    float *pf = &f;
//    float **ppf = &pf;
//
////////////////无符号等基本数据类型
//
//    struct List l;
//    struct List *plist = &l;
//    struct List **pplist = &plist;
//
//    union All all;
//    union All *pall = &all;
//    union All **ppall = &pall;
//
////////////////enum、位段等自定义类型
//    int arr[5];
//    int (*parr) [5] = &arr;
//    int arr[5] = {1,2,3,4,5};
//    int *p = arr;
//    printf("%d\n", *(p+1));
//    char c = 0;
//    char *pc = &c;
//    printf("  pc = %p\n", pc);
//    printf("pc+1 = %p\n", pc + 1);
//    int i = 0;
//    int *pi = &i;
//    printf("  pi = %p\n", pi);
//    printf("pi+1 = %p\n", pi + 1);
//    double d = 0;
//    double *pd = &d;
//    printf("  pd = %p\n", pd);
//    printf("pd+1 = %p\n", pd + 1);
//    return 0;
//}
//int arr[5] = {1, 2, 3, 4, 5};
//    int a = 1;
//int *p = arr;
//printf("%d\n", *((int*)(char*)p + 1));
//    printf("%d\n", *((short*)p + 2));
//#include <stdio.h>
//int main()
//{
//    int a = 40000;
//    int *p = &a;
//    printf("%d\n", *p);
//    return 0;
//}
////
//printf("%d\n", *++p);
//printf("%d\n", ++*p);
//printf("%d\n", *p++);
//#include <stdio.h>
//int main()
//{
////   int arr[2][2] = {{1, 2}, {3, 4}};
////   int (*p)[2] = arr;
////   printf("%d\n", **(p + 1));
//    const char *p1 ="hello";
//    const char *const p2 = "world";
//   return 0;
//}
//#include <stdio.h>
//void FindNum(int (*ps)[5])
//{
//    for (int i = 0; i < 4; ++i)
//    {
//        int sum = 0;
//        int flag = 0;
//        for(int j = 0; j < 5; ++j)
//        {
//            if(*(*(ps + i) + j) <= 85)
//            {
//                flag = 1;
//            }
//            sum += *(*(ps + i) + j);
//        }
//        if(sum / 5 > 90 || flag == 0)
//        {
//            printf("学号：%d\n", i + 1);
//            printf("成绩为：");
//            for (int j = 0; j < 5; ++j)
//            {
//                printf("%d ", *(*(ps + i) + j));
//            }
//            printf("\n");
//        }
//    }
//}
//int main()
//{
//    int score[4][5] = {{90, 76, 89,67,88},
//                       {99,85,99,96,98},
//                       {100,100,98,98,78},
//                       {89,88,87,90,67}};
//    FindNum(score);
//    return 0;
//}
//#include <stdio.h>
//void example(char str[])
//{
//    printf("%d", sizeof(str));
//    return;
//}
//int main(){
//    char str[] = "hello world";
//    example(str);
//    return 0;
//}
//#include <iostream>
//int main()
//{
//    char str[10] = "lll";
//    *str = 's';
//    return 0;
//}
//#include <iostream>
//#include <vector>
//using namespace std;
//int main()
//{
//    vector<int> v1{1,2,3,4,5};
//    vector<int> v2 = {1,2,3,4};
//    cout << v1.size() << endl;
//    cout << v1.capacity() << endl;
//    cout << sizeof(v1) << endl;
//
//    for(auto e : v1)
//    {
//        cout << e << ' ';
//    }
//    for(auto e : v2)
//    {
//        cout << e << ' ';
//    }
//    return 0;
//}
//#include <iostream>
//#include <vector>
//using namespace std;
//vector<vector<int>> generate(int numRows)
//{
//    vector<vector<int>> row(numRows);
//    for(int i = 0; i < numRows; ++i)
//    {
//        if(i == 0)
//            row[i].push_back(1);
//        else
//        {
//            row[i].push_back(1);
//            row[i].push_back(1);
//        }
//        for(int j = 0; j < i + 1; ++j)
//        {
//            if(j != 0 && j != i)
//            {
//               int num = row[i - 1][j - 1] + row[i - 1][j];
//               row[i].insert(row[i].end()-1, num);
//            }
//        }
//    }
//    return row;
//}
//int main()
//{
//    generate(2);
//}
//#include "test.h"
//int main()
//{
//    bit::string s1("hello world");
//    bit::string s2(s1);
//    bit::string s3 = "ooooo";
//    s3 = s1;
//    return 0;
//}
/**
 *
#include "test.h"
namespace bit
{
    string::string(const string &s)
    {
        size_t len = strlen(s._str);
        _str = new char[len + 1];
        strcpy(_str, s._str);
    }
    string::string(const char *str)
    {
        assert(str);
        size_t len = strlen(str);
        _str = new char[len + 1];
        strcpy(_str, str);
    }
    string::~string()
    {
        delete []_str;
        _str = nullptr;
    }

    string& string::operator=(const string &s)
    {
        if(this != &s)
        {
            size_t len = strlen(s._str);
            _str = new char[len + 1];
            strcpy(_str, s._str);
        }
        return *this;
    }
}namespace bit
{
    class string
    {
    public:
        string(const char *str = "");
        string(const bit::string& s);
        bit::string& operator=(const bit::string& s);
        ~string();
    private:
        char *_str;
    };
}
 */
//#include <iostream>
//#include <vector>
//using namespace std;
//int main()
//{
//    vector<int> v1 = {1,2,3,4,5};
//    vector<int>::iterator it;
////    for(auto e : v1)
////    {
////        cout << e << ' ';
////    }
////    cout << endl;
////    it = v1.erase(v1.end() - 1);
////    int a = 2;
////
//////    for(auto e : v1)
//////    {
//////        cout << e << ' ';
//////    }
//////    cout << endl;
////    return 0;
//////}
//#include <iostream>
//#include <vector>
//using namespace std;
//void RecursiveFind(vector<string>& lets, vector<string>& ret, string& digits)
//{
//    int cut = ret.size();
//   for(int s = 0; s < digits.size() - 1; ++s)
//   {
//       if(digits[s] == '7' || digits[s] == '9')
//       {
//           cut = cut / 4;
//       }
//       else
//           cut = cut / 3;
//
//       int j = 0;
//       for (int i = 0; i < ret.size(); ++i)
//       {
//           int cur = cut;
//           while(cur--)
//           {
//               ret[i++] += lets[digits[s] - '0'][j];
//           }
//           --i;
//           ++j;
//           if(j == lets[digits[s] - '0'].size())
//               j = 0;
//       }
//   }
//
//    for (int i = 0; i < ret.size(); ++i)
//    {
//        for (int j = 0; j < lets[digits[digits.size()-1] - '0'].size(); ++j)
//        {
//            ret[i++] += lets[digits[digits.size()-1] - '0'][j];
//        }
//        --i;
//    }
//
//}
//vector<string> letterCombinations(string digits)
//{
//    //输入为空
//    vector<string> empty;
//    if(digits.size() == 0)
//        return empty;
//
//    //不为空
//    vector<string> letters = {"\0", "\0", "abc", "def", "ghi",
//                              "jkl", "mno", "pqrs", "tuv", "wxyz"};
//
//    string::iterator begin = digits.begin();
//    int capa = 1;
//    while(begin != digits.end())
//    {
//        if(*begin == '7' || *begin == '9')
//        {
//            capa *= 4;
//        }
//        else
//            capa *= 3;
//        ++begin;
//    }
//    vector<string> ret(capa);
//    RecursiveFind(letters, ret, digits);
//    return ret;
//}
//int main()
//{
//    vector<string> vs = letterCombinations("738");
//    return 0;
//}
#include <vector>
//#include <iostream>
using namespace std;
//void duplicateZeros(vector<int>& arr)
//{
//    auto begin = arr.begin();
//
//    while(begin != arr.end())
//    {
//        auto cur = begin + 1;
//        if(*begin == 0)
//        {
//            arr.insert(cur, 0);
//        }
//        ++begin;
//    }
//}
//void duplicateZeros(vector<int>& arr)
//{
//    auto begin = arr.begin();
//    auto end = arr.end();
//    int i = 0;
//    while(begin < end)
//    {
//        if(*begin == 0)
//        {
//            auto cur = begin + 1;
//            begin = arr.insert(cur, 0);
//            ++i;
//        }
//        ++begin;
//    }
//    arr.resize(arr.size() - i);
////}
//#include <iostream>
//class A
//{
////public:
////    int fun1();
////private:
////    int _a;
////    static int b;
////};
////int main()
////{
////    cout << sizeof (A) << endl;
////    return 0;
////}
//#include <stdio.h>
//typedef struct student
//{
//    long number;
//    char name[50];
//    float score[3];
//    float average;
//    int rank;
//}ST;
//typedef struct Num
//{
//    ST stdnum[5];
//    int num;
//}Num;
//
//void ScanfPessage(Num *psa)
//{
//    for(int i = 0; i < 5; ++i)
//    {
//        scanf("%ld %s", &psa->stdnum[i].number, psa->stdnum[i].name);
//        for(int j = 0; j < 3; ++j)
//        {
//            scanf("%f", &psa->stdnum[i].score[j]);
//        }
//    }
//}
//void Average(Num *psa)
//{
//    for(int i = 0; i < 5; ++i)
//    {
//        float sum = 0;
//        for (int j = 0; j < 3; ++j)
//        {
//            sum += psa->stdnum[i].score[j];
//        }
//        psa->stdnum[i].average = sum / 3;
//    }
//}
//void Rank(Num *psa)
//{
//    for (int i = 0; i < 5; ++i)
//    {
//        float everyage = psa->stdnum[i].average;
//        int n = i + 1;
//        for(int j = i + 1; j < 5; ++j)
//        {
//            float otherage = psa->stdnum[j].average;
//            if(everyage < otherage)
//            {
//                --n;
//            }
//        }
//        psa->stdnum[i].rank = n;
//    }
//
//}
//void Print(Num *psa)
//{
//    printf("Number: Name:   score:  Average:    rank:\n");
//    for(int i = 0; i < 5; ++i)
//    {
//        printf("%-9ld %-10s", psa->stdnum[i].number, psa->stdnum[i].name);
//        for(int j = 0; j < 3; ++j)
//        {
//            scanf("%-5.1f", psa->stdnum[i].score[j]);
//        }
//        printf("%-10.1f%-d\n", psa->stdnum[i].average, psa->stdnum[i].rank);
//    }
//}
//int main()
//{
//    Num pessage;
//    ScanfPessage(&pessage);
//    Average(&pessage);
//    Rank(&pessage);
//    Print(&pessage);
////    return 0;
////}
//#include "test.h"
//void Test3()
//{
//    wyd::vector<int> v1{1,2,3,4,5};
//    wyd::vector<int> v2(v1);
//    for(auto e : v1)
//    {
//        cout << e << ' ';
//    }
//    cout << endl;
//    for(auto e : v2)
//    {
//        cout << e << ' ';
//    }
//    cout << endl;
//}
//int main()
//{
//    // Test1();
//    // Test2();
//    Test3();
//    return 0;
//}
/**
 * namespace wyd
{
    template<class T>
    class vector
    {
    public:
        typedef T* iterator;
        typedef const T* const_iterator;

        ////////// Construct And Destroy ///////////
        vector()
                : _start(nullptr)
                , _finish(nullptr)
                , _end_of_storage(nullptr)
        {}
        vector(const T& v)
        {
            resever(sizeof(len));
            memcpy(_start, v, sizeof(T)*len);
            _finish = _start + len;
        }
        vector(const vector<T>& v)
        {
            resever(v.capacity());
            memcpy(_start, v._start, sizeof(int)*v.size());
            _finish = _start + v.size();
        }
        // T& operator=()
        // {
//
        // }
        ~vector()
        {
            delete []_start;
            _start = _finish = _end_of_storage = nullptr;
        }

        ////////// iterator ///////////
        iterator begin()
        {
            return _start;
        }
        const_iterator begin() const
        {
            return _start;
        }
        iterator end()
        {
            return _finish;
        }
        const_iterator end() const
        {
            return _finish;
        }

        /////////// Size And Capacity //////////////
        size_t size() const
        {
            return _finish - _start;
        }
        size_t capacity() const
        {
            return _end_of_storage - _start;
        }
        void resever(size_t n)
        {
            if(n > capacity())
            {
                T* new_start = new T[n];
                size_t data = size();
                memcpy(new_start, _start, sizeof(int)*size());
                if(_start != nullptr)
                {
                    delete []_start;
                }
                _start = new_start;
                _finish = _start + data;
                _end_of_storage = _start + n;
            }
        }
        void resize(size_t n, T& data)
        {
            if(n > size())
            {
                if(n > capacity())
                    resever(n);

                memset(_finish, data, n-size());
            }

            _finish = _start + n;
        }
        ///////////// Insert And Delete ////////////////
        void push_back(const T& num)
        {
            if(_finish == _end_of_storage)
            {
                size_t new_capacity = capacity() == 0 ? 4 : 2*capacity();
                resever(new_capacity);
            }
            *_finish = num;
            ++_finish;
        }
        T& operator[](size_t pos)
        {
            assert(pos < size());
            return _start[pos];
        }


    private:
        iterator _start;
        iterator _finish;
        iterator _end_of_storage;
    };
}
//
// */
//#include "test.h"
//void Test1()
//{
//    wyd::vector<int> v1;
//    v1.push_back(1);
//    v1.push_back(2);
//    v1.push_back(3);
//    v1.push_back(4);
//    v1.push_back(4);
//    v1.push_back(4);
//    v1.push_back(4);
//    v1.push_back(4);
//    v1.push_back(4);
//    wyd::vector<int> v2(v1);
//    v1.push_back(40000);
//    v2 = v1;
//    for(auto e : v1)
//    {
//        cout << e << ' ';
//    }
//    cout << endl;
//    for(auto e : v2)
//    {
//        cout << e << ' ';
//    }
//    cout << endl;
////    wyd::vector<int>::iterator it = v1.begin();
////    while(it != v1.end())
////    {
////        cout << *(it++) << ' ';
////    }
////    cout << endl;
//}
//void Test2()
//{
//    wyd::vector<int> v1;
//    v1.push_back(2);
//    v1.push_back(23);
//    v1.push_back(24);
//    v1.push_back(25);
//    v1.push_back(26);
//    for(int i = 0; i < v1.size(); ++i)
//    {
//        cout << v1[i] << ' ';
//    }
//    cout << endl;
//}
//void Test3()
//{
//    wyd::vector<int> v1(10, 2);
//    wyd::vector<int> v2(v1);
//    for(auto e : v1)
//    {
//        cout << e << ' ';
//    }
//    cout << endl;
//    for(auto e : v2)
//    {
//        cout << e << ' ';
//    }
//    cout << endl;
//}
//int main()
//{
//     Test1();
//    // Test2();
////    Test3();
//    return 0;
//}
/**
 * #include <iostream>
#include <assert.h>
using namespace std;
namespace wyd
{
    template<class T>
    class vector
    {
    public:
        typedef T* iterator;
        typedef const T* const_iterator;

        ////////// Construct And Destroy ///////////
        vector()
                : _start(nullptr)
                , _finish(nullptr)
                , _end_of_storage(nullptr)
        {}
        vector(const vector<T>& v)
        {
            _start = new T[v.capacity()];
            _end_of_storage = _start + v.capacity();
            _finish = _start + v.size();
            memcpy(_start, v._start, sizeof(T)*v.size());
        }
        vector(size_t n, const T& value = T())
        {
            _start = new T[n];
            _end_of_storage = _start + n;
            _finish = _start + n;
            memset(_start, value, sizeof(T) * n);
        }
        vector<T>& operator=(const vector<T>& v)
        {
            if(this != &v)
            {
                _start = new T[v.capacity()];
                _end_of_storage = _start + v.capacity();
                _finish = _start + v.size();
                memcpy(_start, v._start, sizeof(T)*v.size());
            }
            return *this;
        }
        ~vector()
        {
            delete []_start;
            _start = _finish = _end_of_storage = nullptr;
        }

        ////////// iterator ///////////
        iterator begin()
        {
            return _start;
        }
        const_iterator begin() const
        {
            return _start;
        }
        iterator end()
        {
            return _finish;
        }
        const_iterator end() const
        {
            return _finish;
        }

        /////////// Size And Capacity //////////////
        size_t size() const
        {
            return _finish - _start;
        }
        size_t capacity() const
        {
            return _end_of_storage - _start;
        }
        void resever(size_t n)
        {
            if(n > capacity())
            {
                T* new_start = new T[n];
                size_t data = size();
                memcpy(new_start, _start, sizeof(int)*size());
                if(_start != nullptr)
                {
                    delete []_start;
                }
                _start = new_start;
                _finish = _start + data;
                _end_of_storage = _start + n;
            }
        }
        void resize(size_t n, const T& data = T())
        {
            if(n > size())
            {
                if(n > capacity())
                    resever(n);

                memset(_finish, data, sizeof(T) * ( n - size() ) );
            }

            _finish = _start + n;
        }
        ///////////// Insert And Delete ////////////////
        void push_back(const T& num)
        {
            if(_finish == _end_of_storage)
            {
                size_t new_capacity = capacity() == 0 ? 4 : 2*capacity();
                resever(new_capacity);
            }
            *_finish = num;
            ++_finish;
        }

        void pop_back()
        {
            assert(size() >= 0);
            --_finish;
        }

        /////////////// [] ///////////////
        T& operator[](size_t pos)
        {
            assert(pos < size());
            return _start[pos];
        }
        const T& operator[](size_t pos) const
        {
            assert(pos < size());
            return _start[pos];
        }
    private:
        iterator _start;
        iterator _finish;
        iterator _end_of_storage;
//    };
//}
// */
//#include <iostream>
//using namespace std;
//vector<int> singleNumber(vector<int>& nums)
//{
//    int max = nums[0];
//    for(int i = 1; i < nums.size(); ++i)
//    {
//        if(max < nums[i])
//        {
//            max = nums[i];
//        }
//    }
//
//    int arr[max];
//    memset(arr, 0, max*sizeof(int));
//    for(int i = 0; i < nums.size(); ++i)
//    {
//        ++arr[nums[i]];
//    }
//
//    vector<int> v;
//    for(int i = 0; i < max; ++i)
//    {
//        if(arr[i] == 1)
//        {
//            v.push_back(i);
//        }
//    }
//
//    return v;
//}
//int main()
//{
//    vector<int> v1 = {1,2,2,3,3,4};
//    vector<int> re = singleNumber(v1);
//    for(auto e : re)
//    {
//        cout << e << ' ';
//    }
//    cout << endl;
//}
//    return 0;// #include <iostream>
// #include <string>
// using namespace std;
// int lengthOfLastWord(string s) 
// {
//     string::iterator end = s.end() - 1;
//     while(*end != ' ')
//     {
//         --end;
//     }
// //     return s.end() - end - 1;
// // }
// // int main()
// // {
// //     string s1 = "hello world hhh";
// //     cout << lengthOfLastWord(s1) << endl;
// //     return 0;
// // }
// #include <stdio.h>
// typedef struct student
// {
//     long number;
//     char name[50];
//     float score[3];
//     float average;
//     int rank;
// }ST;
// typedef struct Num
// {
//     ST stdnum[5];
//     int num;
// }Num;

// void ScanfPessage(Num *psa)
// {
//     for(int i = 0; i < 5; ++i)   
//     {
//         scanf("%ld %s", &psa->stdnum[i].number, psa->stdnum[i].name);
//         for(int j = 0; j < 3; ++j)
//         {
//             scanf("%f", &psa->stdnum[i].score[j]);
//         }
//     }
// }
// void Average(Num *psa)
// {
//     for(int i = 0; i < 5; ++i)
//     {
//         float sum = 0;
//         for (int j = 0; j < 3; ++j)
//         {
//             sum += psa->stdnum[i].score[j];
//         }
//         psa->stdnum[i].average = sum / 3;
//     }
// }
// void Rank(Num *psa)
// {
//     for (int i = 0; i < 5; ++i)
//     {
//         float everyage = psa->stdnum[i].average;
//         int n = 1;
//         for(int j = 0; j < 5; ++j)
//         {
//             float otherage = psa->stdnum[j].average;
//             if(everyage < otherage)
//             {
//                 ++n;
//             }
//         }
//         psa->stdnum[i].rank = n;
//     }
    
// }
// void Print(Num *psa)
// {
//     printf("Number:   Name:         score:    Average:  rank:\n");
//     for(int i = 0; i < 5; ++i)   
//     {
//         printf("%-9ld %-10s", psa->stdnum[i].number, psa->stdnum[i].name);
//         for(int j = 0; j < 3; ++j)
//         {
//             printf("%-5.1f", psa->stdnum[i].score[j]);
//         }
//         printf("%-10.1f%-d\n", psa->stdnum[i].average, psa->stdnum[i].rank);
//     }
// }
// int main()
// {
//     Num pessage;
//     ScanfPessage(&pessage);
//     Average(&pessage);
//     Rank(&pessage);
//     Print(&pessage);
//     return 0;
// }
// #include <vector>
// #include <iostream>
// using namespace std;
//     vector<int> countBits(int n) 
//     {
//         vector<int> v;
//         for(int i = 0; i <= n; ++i)
//         {
//             int count = 0;
//             int j = i;
//             while(j)
//             {
//                 j ^= j - 1;
//                 ++count;
//             }
//             v.push_back(count);
//         }
// //         return v;
// //     }
// // int main()
// // {
// //     countBits(2);
// //     return 0;
// // }
// int bitwiseComplement(int n) 
//     {
//         int nc = n;
//         int count = 0;
//         while(nc)
//         {
//             ++count;
//             nc &= nc - 1;
//         }

//         int ret = 0;
//         for(int i = 0; count > 0; ++i)
//         {
//             if( ((n >> i) & 1) == 0 )
//             {
//                 ret += (1 << i);
//             }
//             else
//             {
//                 --count;
//             }
//         }
//         return ret;
//     }
// int main()
// {
//     bitwiseComplement(5);
// }
// #include "test.h"
// void Test1()
// {
//     bit::vector<int> v1;
//     v1.push_back(1);
//     v1.push_back(2);
//     v1.push_back(3);
//     v1.push_back(4);
//     v1.push_back(5);
//     v1.push_back(6);
//     // v1.push_back(9);
//     // v1.push_back(8);
//     // v1.push_back(1);
//     // v1.push_back(2);
//     // v1.push_back(3);
//     // v1.push_back(4);
//     // v1.push_back(5);
//     // v1.push_back(6);
//     // v1.push_back(7);
//     // v1.push_back(8);
//     // v1.push_back(9);
//     // v1.push_back(1);
//     // v1.push_back(2);
//     bit::vector<int> v2;
//     v2 = v1;
//     v2.pop_back();
//     v2.pop_back();
//     for(bit::vector<int>::iterator it = v2.begin(); it != v2.end(); ++it)
//     {
//         cout << *it << ' ';
//     }
//     cout << endl;
// }
// void Test2()
// {
//     bit::vector<int> v1;
//     v1.push_back(1);
//     v1.push_back(2);
//     v1.push_back(3);
//     v1.push_back(4);
//     v1.push_back(5);
//     v1.push_back(6);
//     v1.push_back(7);
//     for(bit::vector<int>::iterator it = v1.begin(); it != v1.end(); ++it)
//     {
//         cout << *it << ' ';
//     }
//     cout << endl; 
//     // v1.insert(v1.begin(), 100);
//     // v1.insert(v1.begin() + 3, 999);
//     // v1.insert(v1.end() - 1, 80);
//     v1.resize(45, 9);
//     for(bit::vector<int>::iterator it = v1.begin(); it != v1.end(); ++it)
//     {
//         cout << *it << ' ';
//     }
//     cout << endl; 
// Test1(); //测试构造函数，迭代器，尾插，尾删，扩容
    // Test2(); //测试erase删除，// }
// class Solution 
// {
// public:
    // int removeElement(vector<int>& nums, int val) 
    // {
        // vector<int>::iterator cur = nums.begin();
        // vector<int>::iterator dest = nums.begin();
        // while(cur != nums.end())
        // {
            // if(*cur != val)
            // {
                // *dest = *cur;
                // ++dest;
            // }
            // ++cur;
        // }
        // while(dest != nums.end())
        // {
            // nums.pop_back();
        // }
        // return nums.size();
    // }
// };

// #include <iostream>
// using namespace std;
// class A
// {
// public:
//     A& operator++()
//     {
//         *this += 1;
//         return *this;
//     }
//     A operator++(int)
//     {
//         A copy = *this;
//         *this += 1;
//         return copy;
//     }
// private:
//     int _a;
// };
// int main()
// {
//     int a = 1;
//     ++a;
//     return 0;
// }#include <iostream>
// #include <string>
// using namespace std;
// bool isHappy(int n) 
//     {
//         while(n != 1)
//         {
//             int m = 0;
//             static int i = 0;
//             while(n)
//             {
//                 m += pow(n%10, 2);
//                 n /= 10;
//             }
//             ++i;
//             static int p = m;
//             if(i > 1)
//             {
//                 if(p == m)
//                     return false;
//             }
//             n = m;
//         }
//         return true;
//     }
// int main()
// {
//     int a = 0;
//     cin >> a;
//     if(isHappy(a) == true)
//     {
//         cout << "true" << endl;
//     }
//     else
//     {
//         cout << "false" << endl;
//     }
//     return 0;
// class Solution 
// {
// public:
    // bool isPowerOfTwo(int n) 
    // {
        // return (n > 0) && ((n & (n - 1)) == 0);
    // }
// };}// #include <iostream>
// #include <vector>
// using namespace std;
// vector<int> intersection(vector<int>& nums1, vector<int>& nums2) 
//     {
//         vector<int> same;

//         vector<int> bnums = nums1;
//         vector<int> snums = nums2;

//         if(nums1.size() < nums2.size())
//         {
//             bnums = nums2;
//             snums = nums1;
//         }

//         vector<int>::iterator big = bnums.begin();
//         vector<int>::iterator small = snums.begin();

//         while(small != snums.end())
//         {
//             big = bnums.begin();
//             while(big != bnums.end())
//             {
//                 if(*small == *big)
//                 {
//                     same.push_back(*small);
//                 }
//                 ++big;
//             }
//             ++small;
//         }

//         if(same.size() == 0)
//             return same;
//         sort()
//         vector<int> ret;
//         vector<int>::iterator cur = same.begin();
//         vector<int>::iterator next = cur + 1;

//         while(next != same.end())
//         {
//             if(*cur != *next)
//             {
//                 ret.push_back(*cur);
//                 cur = next;
//             }
//             ++next;
//         }

//         ret.push_back(*cur);
//         return ret;
//     }
// int main()
// {
//     vector<int> nums1 = {4,9,5};
//     vector<int> nums2 = {9,4,9,8,4};
//     intersection(nums1, nums2);    
//     return 0;
// }
// class Solution 
// {
// public:
//     vector<int> intersection(vector<int>& nums1, vector<int>& nums2) 
//     {
//         vector<int> same;

//         vector<int> bnums = nums1;
//         vector<int> snums = nums2;

//         if(nums1.size() < nums2.size())
//         {
//             bnums = nums2;
//             snums = nums1;
//         }

//         vector<int>::iterator big = bnums.begin();
//         vector<int>::iterator small = snums.begin();

//         while(small != snums.end())
//         {
//             big = bnums.begin();
//             while(big != bnums.end())
//             {
//                 if(*small == *big)
//                 {
//                     same.push_back(*small);
//                 }
//                 ++big;
//             }
//             ++small;
//         }

//         if(same.size() == 0)
//             return same;
            
//         sort(same.begin(), same.end());
//         vector<int> ret;
//         vector<int>::iterator cur = same.begin();
//         vector<int>::iterator next = cur + 1;

//         while(next != same.end())
//         {
//             if(*cur != *next)
//             {
//                 ret.push_back(*cur);
//                 cur = next;
//             }
//             ++next;
//         }

//         ret.push_back(*cur);
//         return ret;
//     }
// };
/**
 * class Solution 
{
public:
    bool isPowerOfFour(int n) 
    {
        if(n <= 0)
            return false;
        return ( (n & (n - 1)) == 0 ) && ( (n & 0xaaaaaaaa) == 0 );
    }
};
*/// #include <stdio.h>
// int main()
// {
//     int arr[5] = {1,2,3,4,5};
//     printf("arr: %p\n", arr);
//     printf("arr + 1: %p\n", arr + 1);

//     printf("&arr: %p\n", &arr);    
//     printf("&arr + 1: %p\n", &arr + 1);
//     return 0;
// // }
// #include <stdio.h>
// int main()
// {
//     int arr[2][2] = {{1,2},{3,4}};
//     arr[0][1] = 8;
//     int a[5] = {1,2,3,4,5};
//     a[1] = 8;
//     printf("arr[0]:     %p\n", arr[0]);
//     printf("arr[0] + 1: %p\n", arr[0] + 1);
//     return 0;
// }
// #include <stdio.h>
// #include <string.h>
// int main()
// {
//     char ch[5] = {'a', 'b', 'c', 'd', 'e'};
//     printf("%u\n", strlen(ch));
// //     return 0;
// }
/**
 * #include <stdio.h>
// struct T
// {
    // int len;
    // char ch;
    // int *p;
// };
int main()
{
    int arr[2][2];
    int *p[] = {(int *[])arr};
    return 0;
}
class Solution 
{
public:
    char findTheDifference(string s, string t) 
    {
        int sum = 0;
        for(auto e : s)
        {
            sum ^= e;
        }
        for(auto e : t)
        {
            sum ^= e;
        }
        return sum;
    }
};
class Solution 
{
public:
    int maxArea(vector<int>& height) 
    {
       int head = 0;
       int tail = height.size() - 1;
       int max_area = 0;
       while(head != tail)
       {
            int area = abs(head - tail) * (height[head] < height[tail] ? height[head] : height[tail]);
            if(max_area <= area)
                max_area = area;
            if(height[head] > height[tail])
                --tail;
            else
                ++head;
       }
       return max_area;
    }
};
*class Solution 
{
public:
    int triangleNumber(vector<int>& nums) 
    {
        if(nums.size() < 3)
            return 0;
        
        sort(nums.begin(), nums.end());

        int count = 0;
        int c = nums.size() - 1;
        while(c > 1)
        {
            int a = 0; 
            int b = c - 1;
            while(a < b)
            {
                if(nums[a] + nums[b] > nums[c])
                {
                    count += b - a;
                    --b;
                }
                else
                {
                    ++a;
                }
            }
            --c;
        }
       
        return count;
    }
};
string toHex(int num) 
    {
        if(num == 0)
            return "0";

        unsigned int un = (unsigned)num;

        string hex;
        string letters = "abcdef";

        int i = 0;
        for(; un / (int)pow(16, i) != 0; ++i);

        int j = i - 1;
        for(; j >= 0; --j)
        {
            unsigned int n = un / (int)pow(16, j);
            if(n >= 0 && n < 10)
            {
                hex += n + '0';
            }
            else
            {
                hex += letters[n - 10];
            }
            un = un - n * (int)pow(16, j);
        }
        return hex;
    }
    string toHex(int num) 
    {
        if(num == 0)
            return "0";

        unsigned int un = (unsigned)num;

        string hex;
        string letters = "abcdef";

        unsigned int leftone = 0x80000000;
        int i = 0;

        while(leftone)
        {
            while((leftone & un) == 0)
            {
                leftone >>= 1;
                ++i;
            }

            int j = 0;
            int n = (int)pow(2, 31-i);
            while( n / (int)pow(16, j))
            {
                ++j;
            }

            --j;
            while(j >= 0)
            {
                int m = n / pow(16, j);
                if(m >= 0 && m < 10)
                {
                    hex += m + '0';
                }
                else
                {
                    hex += letters[n - 10];
                }
                
                n -= m * pow(16, j);
                if(n == 0)
                    break;
                --j;
            }

            leftone >>= 1;
            ++i;
        }
        return hex;
    }
    class Solution 
{
public:
string toHex(int num) 
    {
        if(num == 0)
            return "0";
        unsigned int un = (unsigned)num;

        string hex;
        string letters = "abcdef";

        unsigned int n = 0xf;
        while(un)
        {
            unsigned int m = un & n;
            hex.insert(hex.begin(),m >= 10 ? letters[m - 10]: m + '0');
            un >>= 4;
        }
        return hex;
    }
};
 vector<vector<int>> mergeArrays(vector<vector<int>>& nums1, vector<vector<int>>& nums2) 
    {
        vector<vector<int>> ret;
        int i = 0;
        int j = 0;

        while(i < nums1.size() && j < nums2.size())
        {
            if(nums1[i][0] == nums2[j][0])
            {
                vector<int> n;
                n.push_back(nums1[i][0]);
                n.push_back(nums1[i][1] + nums2[i][1]);
                ret.push_back(n);
                ++i;
                ++j;
            }
            else if(nums1[i][0] > nums2[j][0])
            {
                ret.push_back(nums2[j]);
                ++j;
            }
            else 
            {
                ret.push_back(nums1[i]);
                ++i;
            }
        }

        while(i < nums1.size())
        {
            ret.push_back(nums1[i]);
            ++i;
        }

        while(j < nums2.size())
        {
            ret.push_back(nums2[j]);
            ++j;
        }
        
        return ret;
    }
// int findComplement(int num) 
// {
//     int n = 0x40000000;

//     while((n & num) == 0)
//     {
//         n >>= 1;
//     }

//     n += n - 1;
//     return n ^ num;
// }
// int findContentChildren(vector<int>& g, vector<int>& s) 
//     {
//         if(s.size() == 0)
//         {
//             return 0;
//         }

//         //排序
//         sort(g.begin(), g.end());
//         sort(s.begin(), s.end());

//         if( *(s.end() - 1) <  *( g.begin() ) )
//         {
//             return 0;
//         }

//         vector<int>::iterator cur_g = g.begin();
//         vector<int>::iterator cur_s = s.begin();

//         int count = 0;
//         while(cur_s != s.end())
//         {
//             if(*cur_s >= *cur_g)
//             {
//                 ++count;
//                 ++cur_g;
//             }
//             if(cur_g == g.end())
//             {
//                 break;
//             }
//             ++cur_s;
//         }
//         return count;
//     }
int main()
{
    // vector<int> g = {1, 2};
    // vector<int> s = {1, 2, 3};
    // findContentChildren(g, s);
    // findComplement(5);
    vector<vector<int>> n1 = {{148,597},{165,623},{306,359},{349,566},{403,646},{420,381},{566,543},{730,209},{757,875},{788,208},{932,695}};
    vector<vector<int>> n2 = {}
    return 0;
}
class Solution 
{
public:
    vector<vector<int>> threeSum(vector<int>& nums) 
    {
        sort(nums.begin(), nums.end());

        if(nums[0] > 0 || nums[nums.size() - 1] < 0) return {};

        vector<vector<int>> ret;
        int tail = nums.size() - 1;

        while(tail > 1)
        {
            int head = 0;
            int cur = tail - 1;

            while(head < cur)
            {
                if(nums[head] + nums[cur] + nums[tail] < 0) ++head;
                else if(nums[head] + nums[cur] + nums[tail] > 0) --cur;
                else
                {
                    ret.push_back({nums[head], nums[cur], nums[tail]});
                    ++head;
                    --cur;
                    while(head < cur && nums[head] == nums[head - 1] ) ++head;
                    while(head < cur && nums[cur] == nums[cur + 1]) --cur;
                }
            }
            --tail;
            while(tail > 1 && nums[tail] == nums[tail + 1]) --tail;
        }
        return ret;
    }
};
class Solution 
{
public:
    vector<vector<int>> fourSum(vector<int>& nums, int target) 
    {
        sort(nums.begin() , nums.end());
        if( (target >= 0 && nums[nums.size() - 1] < 0) || (target <= 0 && nums[0] > 0) )
            return {};

        vector<vector<int>> ret;

        int tail = nums.size() - 1;
        while(tail > 2)
        {
            int sec_tail = tail - 1;
            while(sec_tail > 1)
            {
                int head = 0;
                int cur = sec_tail - 1;
                while(head < cur)
                {
                    long long sum = (long long)nums[head] + (long long)nums[cur] + (long long)nums[sec_tail] + (long long)nums[tail];
                    if(sum > target)
                    {
                        --cur;
                    }
                    else if(sum < target)
                    {
                        ++head;
                    }
                    else
                    {
                        ret.push_back({nums[head], nums[cur], nums[sec_tail], nums[tail]});
                        ++head;
                        --cur;
                        while(head < cur && nums[head] == nums[head - 1]) ++head;
                        while(head < cur && nums[head] == nums[cur + 1]) --cur;
                    }
                }
                --sec_tail;
                while(sec_tail > 1 && nums[sec_tail] == nums[sec_tail + 1]) --sec_tail;
            }
            --tail;
            while(tail > 2 && nums[tail] == nums[tail + 1]) --tail;
        }
        return ret;
    }
};
int findMaximumXOR(vector<int>& nums) 
    {
        //O(nlogn)
        sort(nums.begin(), nums.end());

        int i = 0;
        while( (nums[nums.size() - 1] & (0x40000000 >> i)) == 0)
        {
            ++i;
        }
        int tail = nums.size() - 1;
        while( (nums[tail] & (0x40000000 >> i)) != 0)
        {
            --tail;
        }
        ++tail;

        int ret = 0;
        while(tail < nums.size())
        {
            int head = 0;
            while(head < tail)
            {
                int XOR = nums[head] ^ nums[tail];
                if(ret < XOR)
                {
                    ret = XOR;
                }
                ++head;
            }
            --tail;
        }
        return ret;
    }
    #include <stdio.h>
#include <unistd.h>
int main()
{
    for(int i = 0; i < 2; ++i)
    {
        fork();
        printf("-");
    }
    sleep(2); 
    return 0;
}
#include <iostream>
#include <vector>
using namespace std;
int minSubArrayLen(int target, vector<int>& nums) 
    {
        if(nums.size() == 1 && nums[0] < target)
            return 0;

        int ret = 0;
        int head = 0;
        int max = nums[head];
        int max_pos = 0;
        while(head < nums.size())
        {
            if(max < nums[head])
            {
                max = nums[head];
                max_pos = head;
            }
            if(nums[head] >= target)
                return 1;

            ++head;
        }

        int prev = max_pos - 1;
        int next = max_pos + 1;
        int sum1 = nums[max_pos];
        int sum2 = nums[max_pos];
        while(prev >= 0 || next < nums.size())
        {
            if(prev >= 0) sum1 += nums[prev];
            if(next < nums.size()) sum2 += nums[max_pos];

            if(sum1 >= sum2)
            {
                if(sum1 >= target)
                {
                    ret = max_pos - prev + 1;
                    return ret;
                }
            }
            else
            {
                if(sum2 >= target)
                {
                    ret = next - max_pos + 1;
                    return ret;
                }
            }
            --prev;
            ++next;
        }
        return ret;
    }
int main()
{
    vector<int> nums = {5334,6299,4199,9663,8945,3566,9509,3124,6026,6250,7475,5420,9201,9501,38,5897,4411,6638,9845,161,9563,8854,3731,5564,5331,4294,3275,1972,1521,2377,3701,6462,6778,187,9778,758,550,7510,6225,8691,3666,4622,9722,8011,7247,575,5431,4777,4032,8682,5888,8047,3562,9462,6501,7855,505,4675,6973,493,1374,3227,1244,7364,2298,3244,8627,5102,6375,8653,1820,3857,7195,7830,4461,7821,5037,2918,4279,2791,1500,9858,6915,5156,970,1471,5296,1688,578,7266,4182,1430,4985,5730,7941,3880,607,8776,1348,2974,1094,6733,5177,4975,5421,8190,8255,9112,8651,2797,335,8677,3754,893,1818,8479,5875,1695,8295,7993,7037,8546,7906,4102,7279,1407,2462,4425,2148,2925,3903,5447,5893,3534,3663,8307,8679,8474,1202,3474,2961,1149,7451,4279,7875,5692,6186,8109,7763,7798,2250,2969,7974,9781,7741,4914,5446,1861,8914,2544,5683,8952,6745,4870,1848,7887,6448,7873,128,3281,794,1965,7036,8094,1211,9450,6981,4244,2418,8610,8681,2402,2904,7712,3252,5029,3004,5526,6965,8866,2764,600,631,9075,2631,3411,2737,2328,652,494,6556,9391,4517,8934,8892,4561,9331,1386,4636,9627,5435,9272,110,413,9706,5470,5008,1706,7045,9648,7505,6968,7509,3120,7869,6776,6434,7994,5441,288,492,1617,3274,7019,5575,6664,6056,7069,1996,9581,3103,9266,2554,7471,4251,4320,4749,649,2617,3018,4332,415,2243,1924,69,5902,3602,2925,6542,345,4657,9034,8977,6799,8397,1187,3678,4921,6518,851,6941,6920,259,4503,2637,7438,3893,5042,8552,6661,5043,9555,9095,4123,142,1446,8047,6234,1199,8848,5656,1910,3430,2843,8043,9156,7838,2332,9634,2410,2958,3431,4270,1420,4227,7712,6648,1607,1575,3741,1493,7770,3018,5398,6215,8601,6244,7551,2587,2254,3607,1147,5184,9173,8680,8610,1597,1763,7914,3441,7006,1318,7044,7267,8206,9684,4814,9748,4497,2239};
    int re = minSubArrayLen(697439, nums);
    printf("%d\n", re);
    return 0;
}
// #include <stdio.h>
// #include <stdlib.h>
// #include <time.h>
// int main() 
// {
//     srand(time(nullptr));
//     int i = rand() % 216;
//     printf("%d\n", i);
//     return 0;
// }
/// #include <stdio.h>
// int main()
// {
//     int arr[3] = {(),(1,2,3),(1,2,3)};
//     printf("%d\n",arr[0]);
//     // char str[] = "abcde";
// //     // // const char *p = "abcde";
// //     // // // printf("%lu %lu\n", sizeof(str), sizeof(p));
// //     return 0;
// // }
// #include <stdio.h>
// #include <stdlib.h>
// #include <string.h>
// void MallocMem(char** pc) 
// {
//     *pc = (char*) malloc (100);
//     return;
// }
 
// int main() 
// {
//     char *str=NULL;
//     MallocMem(&str);
//     strcpy(str,"hello ");
//     strcat(str, "world");
//     printf("%s\n",str);
//     return 0;
class Solution 
{
public:
    void Delete(string& s)
    {
        string::iterator cur_s = s.begin();
        while(cur_s != s.end())
        {
            if(*cur_s !=  '#')
                ++cur_s;
            else
            {
                cur_s = s.erase(cur_s);
                if(cur_s != s.begin())
                    cur_s = s.erase(cur_s - 1);
            }
        }
    }
    bool backspaceCompare(string s, string t) 
    {
        Delete(s);
        Delete(t);
        return s == t;   
    }
};
// }// #define NEW 1
// // #define READY 2
// // #define RUNNING 3
// // ...
// // struct task_struct
// // {
// //     int status;
// //     ...;
// // };
// static const char * const task_state_array[] = {
// #include <iostream>
// using namespace std;
// int lengthOfLongestSubstring(string s) 
//     {
//         if(s.size() == 0)
//             return 0;
//         int head = 0;
//         int cur = 1;
//         int count = 1;
//         int max = 0;
//         while(cur < s.size())
//         {
//             size_t findnum = s.find(&s[cur] ,head, cur - head - 1);
//             if(findnum != -1)
//             {
//                 head = findnum + 1;
//                 count = cur - head + 1;
//             }
//             else
//             {
//                 ++cur;
//                 ++count;
//                 if(max < count)
//                     max = count;
//             }
//         }
//         return count;
//     }
// int main()
// {
//     lengthOfLongestSubstring("abcabcbb");
//     // const char *s = "a";
//     // string b = "abcdeaaaa";
//     // size_t r = b.find(s, 5, 1);
//     return 0;
// }// 
// #include <stdio.h> 
// int main() 
// {
    // char str1[] = "hello world";  
    // char str2[] = "hello world";  
//  
    // const char str3[] = "hello world";  
    // const char str4[] = "hello world";  
//  
    // const char* pstring1 = "hello world";  
    // const char* pstring2 = "hello world";  
//  
    // if(str1 == str2) 
        // printf("true,");
    // else
        // printf("false,");
// 
    // if(str3 == str4) 
        // printf("true,");
    // else
        // printf("false,");
// 
    // if(pstring1 == pstring2) 
        // printf("true\n");
    // else
        // printf("false\n");
        // 
    // return 0;
// }

 * class Solution 
{
public:
    vector<int> diStringMatch(string s) 
    {
        vector<int> ret(s.size() + 1);
        int head = 0, tail = s.size();

        for(int i = 0; i < s.size(); ++i)
        {
            ret[i] = ((s[i] == 'I') ? head++ : tail--);
        }
        ret[s.size()] = head;

        return ret;
    }
};
int a[3][4] = {1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23};
    int(*p)[4] = a, i, j, k = 0;
    for (i = 0; i < 3; i++)
        for (j = 0; j < 2; j++)
            k = k + *(*(p + i) + j);
    printf("%d", k);
#include <cmath>
#include <iostream>
using namespace std;
int main() 
{
    int num = 0;
    cin >> num;
    int count = 1;
    for(int i = 1; i <= num; ++i)
    {
        int j = 0;
        int n = i;
        while(n)
        {
            n /= 10;
            ++j;
        }
        if((i * i) % (int)pow(10, j) == i)
        {
            ++count;
        }
    }
    cout << count << endl;
    return 0;
}
#include <iostream>
using namespace std;
bool TruePrime(int n)
{
    for(int j = 2; j < n; ++j)
    {
        if(n != 2 && n % j == 0)
        {
            return false;
        }
    }
    return true;
}
int main() 
{
    int N = 0;
    cin >> N; //输入
    int count = 0; //计数
    for(int i = 2; i < N; ++i)
    {
        if(TruePrime(i))
        {
            ++count;
        }
    }
    cout << count << endl;
    return 0;
}
// using namespace std;
    // int reverseBits(int num) 
    // {
    //     int count_1 = 0;
    //     int count_max = 0;
    //     for(int i = 0; i < 32;)
    //     {
    //         if(num & (1 << i) != 0)
    //         {
    //             ++count_1;
    //             ++i;
    //         }
    //         else
    //         {
    //             ++i;
    //             ++count_1;
    //             int j = i;
    //             while(i < 32 && num & (1 << i) != 0)
    //             {
    //                 ++i;
    //                 ++count_1;
    //             }
    //             count_max = count_max < count_1 ? count_1 : count_max;
    //             count_1 = 0;
    //             i = j;
    //         }
    //     }
    //     count_max = count_max < count_1 ? count_1 : count_max;
    //  s   return count_max;
    // }
#include <vector>
    int HammingDistance(int num1, int num2)
    {
        int dif = num1 ^ num2;
        int count = 0;
        while(dif != 0)
        {
            dif = dif & (dif - 1);
            ++count;
        }
        return count;
    }
    int totalHammingDistance(vector<int>& nums) 
    {
        if(nums.size() == 0 || nums.size() == 1)
        {
            return 0;
        }
        int total = 0;

        sort(nums.begin(), nums.end());

        for(int i = 0; i < nums.size() - 1; ++i)
        {
            int same_num = 1;
            while(nums[i] == nums[i + 1])
            {
                ++i;
                ++same_num;
            }

            for(int j = i + 1; j < nums.size(); ++j)
            {
                total += HammingDistance(nums[i], nums[j]);
            }
            if(same_num != 1)
                total *= same_num;
        }
        return total;
    }
int main()
{
    vector<int> nums = {7331, 1337};
    int total = totalHammingDistance(nums);
    cout << total << endl;
    return 0;
}
class Solution
{
public:
    int trailingZeroes(int n)
    {
        int count_five = 0; //找因数中 5 的个数
        while(n >= 5)
        {
            n /= 5;
            count_five += n;
        }
        return count_five;
    }
};
// #include <iostream>
// #include <string>
// using namespace std;

// int main()
// {
//     string str;
//     cin >> str;
//     //0-48,9-57
//     int cur = 0;
//     int next = 0;
//     int count = 0;
//     int begin = 0;
//     int end = 0;
//     for(int i = 0; str[i];)
//     {
//         next = cur;
//         //找数字
//         while(str[i] && (str[i] < '0' || str[i] > '9'))
//         {
//             ++next;
//             ++i;
//         }
//         cur = next;
//         //找非数字
//         while(str[i] && str[i] >= '0' && str[i] <= '9')
//         {
//             ++cur;
//             ++i;
//         }
//         if(count < cur - next)
//         {
//             count = cur - next;
//             begin = next;
//             end = cur;
//         }
//     }
//     while(begin < end)
//     {
//         cout << str[begin++];
//     }
//     cout << endl;
//     return 0;
// }
// #include <iostream>
// #include <list>
// using namespace std;
// int main()
// {
//     list<int> lt;
//     lt.push_back(1);
//     lt.push_back(2);
//     lt.push_back(3);
//     lt.push_back(4);
//     lt.push_back(5);
//     for(auto e : lt)
//     {
//         cout << e << " ";
//     }
//     cout << endl;
//     return 0;
// }
// #include <iostream>
// #include <string>
// using namespace std;
// class Data
// {
//     public:
//         // void Init(size_t year = 2003, size_t month = 10, size_t day = 16)
//         // {
//         //     _year = year;
//         //     _month = month;
//         //     _day = day;
//         // }
//         void Print()
//         {
//             cout << _year << "." << _month << "." << _day << endl;
//         }
//         Data()
//         {
//             _year = 0;
//             _month = 0;
//             _day = 0;
//         }
//         Data(size_t year, size_t month, size_t day)
//         {
//             _year = year;
//             _month = month;
//             _day = day;
//         }
//         ~Data()
//         {
//             _year = 0;
//             _month = 0;
//             _day = 0;
//         }

//     private:
//         size_t _year;
//         size_t _month;
//         size_t _day;
// };
//  int lengthOfLongestSubstring(string s)
//     {
//         string::iterator left = s.begin();
//         string::iterator right = s.begin();
//         int count = 0;
//         int arr[128] = {0};
//         while(right != s.end())
//         {
//             while(right != s.end() && arr[*right] < 2)
//             {
//                 ++arr[*right];
//                 if(arr[*right] == 2)
//                     break;
//                 ++right;
//             }
//             count = count > (right - left) ? count : (right - left);

//             if(right == s.end())
//                 return count;

//             int i = 0;
//             for(; i < 128; ++i)
//             {
//                 if(arr[i] == 2)
//                 {
//                     arr[i] = 1;
//                     break;
//                 }
//             }

//             while(left != right)
//             {
//                 if(*left != i)
//                     ++left;
//                 else
//                     {
//                         ++left;
//                         break;
//                     }
//             }
//             ++right;
//         }
//         return count;
//     }
// int main()
// {
//     // Data data;
//     // Data data2(1,2,3);
//     // data.Print();
//     // data2.Print();
//     string s = "aabcde";
//     lengthOfLongestSubstring(s);
//     return 0;
// }
// #include <stdio.h>
// #include <string.h>
// int main()
// {
//     char p1[15]="abcd", *p2="ABCD", str[50]="xyz";
//     strcpy(str + 2, strcat(p1+2, p2+1));
//     printf("%s", str);
//     return 0;
// }
// #include <iostream>
// #include <istream>
// #include <string>
// #include <stdlib.h>
// using namespace std;
// void Abbreviations(string& str)
// {
//     if(str.size() >= 10)
//     {
//         char begin = str[0];
//         char end = str[str.size() - 1];
//         str = begin;
//         int size = str.size();
//         while(size)
//         {
//             str.push_back(size / 10 + '0');
//             size %= 10;
//         }
//         str.push_back(end);
//     }
//     cout << str << endl;
// }
// int main()
// {
//     int scanf_num_str = 0;
//     cin >> scanf_num_str;
//     getchar();
//     for(int i = 0; i < scanf_num_str; ++i)
//     {
//         string str;
//         getline(cin, str);
//         Abbreviations(str);
//     }
//     return 0;
// }
 * #include <cstdio>
#include <iostream>
#include <istream>
#include <string>
using namespace std;
void Abbreviations(string& str)
{
    if(str.size() >= 10)
    {
        char begin = str[0];
        char end = str[str.size() - 1];
        int size = str.size() - 2;
        str = begin;
        if(size >= 10)
            str.push_back(size / 10 + '0');
        str.push_back(size % 10 + '0');
        str.push_back(end);
    }
    cout << str << endl;
}
int main()
{
    int scanf_num_str = 0;
    cin >> scanf_num_str;
    getchar();
    for(int i = 0; i < scanf_num_str; ++i)
    {
        string str;
        getline(cin, str);
        Abbreviations(str);
    }
    return 0;
}
class Solution
{
public:
    string replaceSpaces(string S, int length)
    {
        string newstr;
        string str = "%20";
        for(int i = 0; i < length; ++i)
        {
            if(S[i] != ' ')
                newstr.push_back(S[i]);
            else
            {
                newstr += str;
            }
        }
        return newstr;
    }
};
*/
// #include <iostream>
// #include <string>
// using namespace std;
// union D
// {
//     int d1;
//     float d2;
// }d;
//   string compressString(string S)
//     {
//         int left = 0;
//         int right = 0;
//         string ret_str;
//         while(right <= S.size())
//         {
//             if(S[left] != S[right])
//             {
//                 ret_str.push_back(S[left]);
//                 int count = right - left;
//                 string::iterator i = ret_str.end();
//                 while(count)
//                 {
//                     ret_str.insert(i, count % 10 + '0');
//                     --i;
//                     count /= 10;
//                 }
//                 left = right;
//             }
//             else
//                 ++right;
//         }
//         if(S.size() <= ret_str.size())
//             return S;
//         else
//             return ret_str;
//     }
// int main()
// {
//     // d.d2 = 10;
//     // cout << d.d1 << endl;
//     string S = "aaaaaaaaaabbccccccccccddssss";
//     compressString(S);
//     return 0;
// }
// #include <iostream>
// using namespace std;
//     int exchangeBits(int num)
//     {
//         int c = 3;
//         for(int i = 0; i < 32; i += 2)
//         {
//             int a = (num >> i) & 1;
//             int b = (num >> (i + 1)) & 1;
//             if(a != b)
//                 num ^= c;
//             c <<= 2;
//         }
//         return num;
//     }
// int main()
// {
//     int num = exchangeBits(29);
//     cout << num << endl;
//     return 0;
// }
// #include <iostream>
// using namespace std;
// int main()
// {
//     int num = 0;
//     cin >> num;
//     size_t count = 0;
//     for(int i = 1; i < num + 1; ++i)
//     {
//         if(i % 7 == 0) //7的倍数
//            ++count;
//         //数字中包含7
//         else
//         {
//             int j = i;
//             while(j)
//             {
//                 if(j % 10 == 7)
//                 {
//                     ++count;
//                     break;
//                 }
//                 j /= 10;
//             }
//         }
//     }
//     cout << count << endl;
//     return 0;
// }
// #include <iostream>
// #include <list>
// #include <cassert>
// using namespace std;

// class MinStack
// {
// public:
//     MinStack()
//     {}

//     void push(int x)
//     {
//         lt.push_back(x);
//     }

//     void pop()
//     {
//         assert(!lt.empty());
//         lt.pop_back();
//     }

//     int top()
//     {
//         return *(--lt.end());
//     }

//     int getMin()
//     {
//         int min = *lt.begin();
//         list<int>::iterator next = ++lt.begin();
//         while(next != lt.end())
//         {
//             min = min > *next ? *next : min;
//             ++next;
//         }
//         return min;
//     }
// private:
//     typedef list<int> Node;
//     Node lt;
// };
// int main()
// {
//     return 0;
// }
// class MinStack
// {
// public:
//     MinStack()
//     {}

//     void push(int x)
//     {
//         sk.push(x);
//         if(minsk.empty() || sk.top() <= minsk.top())
//             minsk.push(x);
//     }

//     void pop()
//     {
//         if(sk.top() == minsk.top())
//             minsk.pop();
//         sk.pop();
//     }

//     int top()
//     {
//         return sk.top();
//     }

//     int getMin()
//     {
//         return minsk.top();
//     }
// private:
//     stack<int> sk;
//     stack<int> minsk;
// };
// #include "fun.h"
// void function_1()
// {
//     wyd::List<int> lt;
//     lt.push_back(1);
//     lt.push_back(2);
//     lt.push_back(3);
//     lt.push_back(4);
//     lt.push_back(5);
//     for(auto e : lt)
//     {
//         cout << e << ' ';
//     }
//     cout << endl;
//     // cout << lt.size() << endl;
//     // lt.pop_back();
//     // lt.pop_front();
//     lt.push_front(199);
//     lt.push_back(199);
//        for(auto e : lt)
//     {
//         cout << e << ' ';
//     }
//     cout << endl;
// }
// int main()
// {
//     function_1();
//     return 0;
// }
/**
* #include <iostream>
#include <cassert>
using namespace std;
namespace wyd
{
    //////////////////////////////////////链表节点////////////////////////////////////
    template <class T>
    struct ListNode
    {
        typedef ListNode<T> Node;
        ListNode(const T& val = T())
            : _prev(nullptr)
            , _next(nullptr)
            , _val(val)
            {}
        Node* _prev;
        Node* _next;
        T _val;
    };
//////////////////////////////////////iterator 指针////////////////////////////////////
    template <class T>
    struct _list_iterator
        {
            typedef _list_iterator<T> self;
            typedef ListNode<T> Node;
            Node* it;

            _list_iterator(Node* x)
                :it(x)
            {}

            self& operator++()
            {
                it = it->_next;
                return *this;
            }

            self operator++(int) //后置++
            {
                self other = *this;
                it = it->_next;
                return other;
            }

            self& operator--()
            {
                it = it->_prev;
                return *this;
            }

            self operator--(int) //后置--
            {
                self other = *this;
                it = it->_prev;
                return other;
            }
            T& operator*()
            {
                return it->_val;
            }
            bool operator!=(const self& other)
            {
                return it != other.it;
            }
            bool operator==(const self& other)
            {
                return it == other.it;
            }

        };
    //带头双向循环链表
    template <class T>
    class List
    {
    public:
        List()
        {
           List_Create();
        }
        List(int n, const T& value = T())
        {
            List_Create();
            while(n--)
            {
                push_back(value);
            }
        }
        void List_Create()
        {
            _head = new Node;
            _head->_next = _head;
            _head->_prev = _head;
        }
        ~List()
        {
            clear();
            delete _head;
            _head = nullptr;
        }
        void clear()
        {
            iterator cur = begin();
            while(cur != end())
            {
                cur = erase(cur);
            }
        }
        void push_back(const T& val) { insert(end(), val); }
        void push_front(const T& val) { insert(begin(), val); }

        void pop_back() { erase(--end()); }
        void pop_front() { erase(begin()); }

        typedef _list_iterator<T> iterator;
        iterator begin() { return (iterator)_head->_next; }
        iterator end() { return (iterator)_head; }

        iterator insert(iterator pos, const T& val)
        {
            Node* newnode = new Node(val);
            Node* prev = pos.it->_prev;
            newnode->_next = pos.it;
            newnode->_prev = prev;
            prev->_next = newnode;
            pos.it->_prev = newnode;
            return newnode;
        }
        iterator erase(iterator pos)
        {
            assert(pos != end());
            Node* prev = pos.it->_prev;
            Node* next = pos.it->_next;
            prev->_next = next;
            next->_prev = prev;
            delete pos.it;
            return next;
        }
        void swap(List<T>& other)
        {
            std::swap(_head, other._head);
        }
        List<T>& operator=(List<T> lt)
        {
            swap(lt);
            return *this;
        }
        size_t size()
        {
            int count = 0;
            iterator cur = begin();
            while(cur != end())
            {
                ++count;
                ++cur;
            }
            return count;
        }
        bool empty()
        {
            return begin() == end();
        }
    private:
        typedef ListNode<T> Node;
        Node* _head;
    };
}
 #include <vector>
class Solution
{
public:
    bool IsPopOrder(vector<int>& pushV, vector<int>& popV)
    {
        //判断两个栈的元素是否相同
        int num1 = 0;
        for(auto e : pushV) num1 ^= e;
        for(auto e : popV)  num1 ^= e;
        if(num1 != 0) return false;

        vector<int>::iterator push_num = pushV.begin();
        vector<int>::iterator pop_num = popV.begin();

        while(*push_num!= *pop_num) ++push_num;
        push_num = pushV.erase(push_num);
        ++pop_num;

        for(; pop_num != popV.end(); ++pop_num)
        {
            //向下找一个,保证下面有元素
            if(push_num != pushV.begin() && *(push_num - 1) == *pop_num)
                push_num = pushV.erase(push_num - 1);
            //该位置，保证该位置有元素
            else if(push_num != pushV.end() && *push_num == *pop_num)
                push_num = pushV.erase(push_num);
            //向上找多个，保证上面有元素
            else if(push_num != pushV.end() && (++push_num) != pushV.end())
            {
                int flag = 0;
                while(push_num != pushV.end())
                {
                    if(*(push_num) == *pop_num)
                    {
                        flag = 1;
                        push_num = pushV.erase(push_num);
                        break;
                    }
                    else
                        ++push_num;
                }
                if(push_num == pushV.end() && flag == 0)
                    return false;
            }
            //找不到
            else
                return false;
        }
        return true;
    }
};**
        //判断两个栈的元素是否相同
        int num1 = 0;
        for (auto e : pushV)
            num1 ^= e;
        for (auto e : popV)
            num1 ^= e;
        if (num1 != 0)
            return false;

        typedef vector<int>::iterator iterator;
        iterator push_num = pushV.begin();
        iterator pop_num = popV.begin();

        while (*push_num != *pop_num)
            ++push_num;
        push_num = pushV.erase(push_num);
        ++pop_num;*/
// for(; pop_num != popV.end(); ++pop_num)
// {
//     //向下找一个,保证下面有元素
//     if(push_num != pushV.begin() && *(push_num - 1) == *pop_num)
//         push_num = pushV.erase(push_num - 1);
//     //该位置，保证该位置有元素
//     else if(push_num != pushV.end() && *push_num == *pop_num)
//         push_num = pushV.erase(push_num);
//     //向上找多个，保证上面有元素
//     else if(push_num != pushV.end() && (++push_num) != pushV.end())
//     {
//         int flag = 0;
//         while(push_num != pushV.end())
//         {
//             if(*(push_num) == *pop_num)
//             {
//                 flag = 1;
//                 push_num = pushV.erase(push_num);
//                 break;
//             }
//             else
//                 ++push_num;
//         }
//         if(push_num == pushV.end() && flag == 0)
//             return false;
//     }
//     //找不到
//     else
//         return false;
// }
// return true;
//#include <vector>
//class Solution
//{
//public:
//    bool IsPopOrder(vector<int>& pushV, vector<int>& popV)
//    {
//        stack<int> sk;
//        int push_cur = 0;
//        int pop_cur = 0;
//
//        while(push_cur < pushV.size())
//        {
//            sk.push(pushV[push_cur++]);
//            while(!sk.empty() && popV[pop_cur] == sk.top())
//            {
//                sk.pop();
//                ++pop_cur;
//            }
//        }
//        if(!sk.empty())
//            return false;
//        return true;
//    }
//};
//class Solution
//{
//public:
//    int evalRPN(vector<string>& tokens)
//    {
//        if(tokens.size() == 1)
//        {
//            return stoi(tokens[0]);
//        }
//        //数字
//        stack<string> num;
//        int cur = 0;
//        while(cur < tokens.size())
//        {
//            while(tokens[cur] != "+" && tokens[cur] != "-" && tokens[cur] != "*" && tokens[cur] != "/")
//            {
//                num.push(tokens[cur++]);
//            }
//
//            int num2 = stoi(num.top());
//            num.pop();
//            int num1 = stoi(num.top());
//            num.pop();
//
//            if(tokens[cur] == "+")
//                num.push(to_string(num1 + num2));
//            if(tokens[cur] == "-")
//                num.push(to_string(num1 - num2));
//            if(tokens[cur] == "*")
//                num.push(to_string(num1 * num2));
//            if(tokens[cur] == "/")
//                num.push(to_string(num1 / num2));
//            ++cur;
//        }
//        return stoi(num.top());
//    }
//};
//*/
//#include "test.h"
//
//    int binary_search(vector<int>& nums, int& begin, int& end, int& target)
//    {
//        while(begin <= end)
//        {
//            int mid = (begin + end) / 2;
//            if(nums[mid] > target)
//            {
//                end = mid - 1;
//            }
//            else if(nums[mid] < target)
//            {
//                begin = mid + 1;
//            }
//            else
//                return mid;
//        }
//        return -1;
//    }
//int search(vector<int>& nums, int target)
//    {
//        int begin_j = 0;
//        int end_j = 0;
//
//        int begin_i = 0;
//        int end_i = nums.size() - 1;
//
//        while(end_j + 1 < nums.size())
//        {
//            if(nums[end_j] < nums[end_j + 1])
//                ++end_j;
//            else
//                break;
//        }
//        if(end_j + 1 < nums.size())
//            begin_i = end_j + 1;
//
//        if(nums[begin_j] <= target &&  target <= nums[end_j])
//        {
//            return binary_search(nums, begin_j, end_j, target);
//        }
//        else if(nums[begin_i] <= target && target <= nums[end_i])
//        {
//            return binary_search(nums, begin_i, end_i, target);
//        }
//        else
//            return -1;
//    }
//int main()
//{
//    vector<int> nums = {1, 3};
//    int ret = search(nums, 0);
//    cout << ret << endl;
//    return 0;
    // wyd::Stack<int> sk;
    // sk.push(1);
    // sk.push(2);
    // sk.push(3);
    // sk.push(4);
    // sk.push(5);
    // sk.push(6);
    // while(!sk.empty())
    // {
    //     cout << sk.top() << " ";
    //     sk.pop();
    // }
    // cout << endl;
    // wyd::priority_queue<int, vector<int>, less<int>> piq;
    // piq.push(5);
    // piq.push(50);
    // piq.push(1);
    // piq.push(4);
    // piq.push(3);
    // piq.push(2);
    // piq.push(0);
    // while(!piq.empty())
    // {
    //     cout << piq.top() << " ";
    //     piq.pop();
    // }
    // cout << endl;
    //  return 0;
//}
/**
* // {
//     template <class T, class Container = deque<T>>

//     class Stack
//     {
//     public:
//         Stack()
//         {}
//         void push(const T& val)
//         {
//             node.push_back(val);
//         }
//         void pop()
//         {
//             node.pop_back();
//         }
//         T& top()
//         {
//             return node.back();
//         }
//         bool empty()
//         {
//             return node.empty();
//         }
//         int size()
//         {
//             return node.size();
//         }

//     private:
//         Container node;
//     };

//     template <class T, class Container = deque<T>>
//     class queue
//     {
//     public:
//         queue()
//         {}
//         void push_back(const T& val)
//         {
//             lt.push_back(val);
//         }
//         void pop_front()
//         {
//             lt.pop_front();
//         }
//         bool empty()
//         {
//             return lt.empty();
//         }
//         int size()
//         {
//             return lt.size();
//         }
//         T& front()
//         {
//             return lt.front();
//         }
//         T& back()
//         {
//             return lt.back();
//         }
//     private:
//         list<T> lt;
//     };
//     ////////////////////////////////////////////////////////////////////
//     template <class T>
//     class less
//     {
//     public:
//         bool operator()(const T& x, const T& y)
//         {
//             return x < y;
//         }
//     };

//     template <class T>
//     class greater
//     {
//     public:
//         bool operator()(const T& x, const T& y)
//         {
//             return x > y;
//         }
//     };

//     template <class T, class Container = vector<T>, class Compare = greater<T>>
//     class priority_queue
//     {
//     public:
//         priority_queue()
//         {}
//         void ADjust_Up(size_t child)
//         {

//             while(child != 0)
//             {
//                 size_t parent = (child - 1) / 2;
//                 if(_com(_con[parent], _con[child]))
//                 {
//                     swap(_con[parent], _con[child]);
//                     child = parent;
//                 }
//                 else
//                     break;
//             }
//         }
//         void push(const T& val)
//         {
//             _con.push_back(val);
//             ADjust_Up(size() - 1);
//         }
//         void Adjust_Down(int end_num)
//         {
//             int parent = 0;
//             int child = parent * 2 + 1;
//             while(child <= end_num)
//             {
//                 if(child + 1 <= end_num && _com(_con[child], _con[child + 1]))
//                     child = child + 1;
//                 if(_com(_con[parent], _con[child]))
//                 {
//                     swap(_con[parent], _con[child]);
//                     parent = child;
//                     child = parent * 2 + 1;
//                 }
//                 else
//                     break;
//             }
//         }
//         void pop()
//         {
//             swap(_con[0], _con[size() - 1]);
//             _con.pop_back();
//             Adjust_Down(size() - 1);
//         }
//         T& top()
//         {
//             return _con[0];
//         }
//         int size()
//         {
//             return _con.size();
//         }
//         bool empty()
//         {
//             return _con.empty();
//         }
//     private:
//         Container _con;
//         Compare _com;
//     };
namespace wyd
{
    template <class T, class iterator>
    struct reverse_iterator
    {
        typedef reverse_iterator<T, iterator> self;
        iterator _rit;

        reverse_iterator(iterator rit)
            : _rit(rit)
            {}
        self& operator++()
        {
            --_rit;
            return *this;
        }
        self operator++(int)
        {
            self newit(*this);
            --_rit;
            return newit;
        }
        self& operator--()
        {
            ++_rit;
            return *this;
        }
        self operator--(int)
        {
            self new_self(*this);
            ++_rit;
            return new_self;
        }
        bool operator!=(const self& s)
        {
            return _rit != s._rit;
        }
        bool operator==(const self& s)
        {
            return _rit == s._rit;
        }
        T& operator*()
        {
            return *_rit;
        }

    };
}
 namespace wyd
{
   template<class T>
   struct ListNode
   {
       ListNode<T>* _next;
       ListNode<T>* _prev;
       T _data;

       ListNode(const T& x = T())
               :_next(nullptr)
               ,_prev(nullptr)
               ,_data(x)
       {}
   };

   template<class T>
   struct _list_iterator
   {
       typedef ListNode<T> Node;
       typedef _list_iterator<T> self;
       Node* _node;

       _list_iterator(Node* x)
               :_node(x)
       {}

       // ++it
       self& operator++()
       {
           _node = _node->_next;
           return *this;
       }

       // it++
       self operator++(int)
       {
           self tmp(*this);
           _node = _node->_next;
           return tmp;
       }

       self& operator--()
       {
           _node = _node->_prev;
           return *this;
       }

       self operator--(int)
       {
           self tmp(*this);
           _node = _node->_prev;
           return tmp;
       }

       T& operator*()
       {
           return _node->_data;
       }

       bool operator!=(const self& s)
       {
           return _node != s._node;
       }

       bool operator==(const self& s)
       {
           return !(*this != s);
       }

   };

   template<class T>
   class list
   {
       typedef ListNode<T> Node;
   public:
       typedef _list_iterator<T> iterator;

       iterator begin()
       {
           return iterator(_head->_next);
       }

       iterator end()
       {
           return iterator(_head);
       }

       typedef reverse_iterator<T, iterator> reverse_iterator;
       reverse_iterator rbegin()
       {
            return reverse_iterator(end());
       }
       reverse_iterator rend()
       {
            return reverse_iterator(begin());
       }
       void empty_init()
       {
           _head = new Node;
           _head->_next = _head;
           _head->_prev = _head;
       }

       list()
       {
           empty_init();
       }

       void clear()
       {
           iterator it = begin();
           while (it != end())
           {
               it = erase(it);
           }
       }

       ~list()
       {
           clear();

           delete _head;
           _head = nullptr;
       }

       list(list<T>& lt)
       {
           empty_init();

           for (const auto& e : lt)
           {
               push_back(e);
           }
       }


       void swap(list<T>& tmp)
       {
           std::swap(_head, tmp._head);
       }

       list<T>& operator=(list<T> lt)
       {
           swap(lt);
           return *this;
       }

       void push_back(const T& x)
       {
           insert(end(), x);
       }

       void push_front(const T& x)
       {
           insert(begin(), x);
       }

       void pop_back()
       {
           erase(--end());
       }

       void pop_front()
       {
           erase(begin());
       }

       iterator insert(iterator pos, const T& x)
       {
           Node* cur = pos._node;
           Node* prev = cur->_prev;
           Node* newnode = new Node(x);

           prev->_next = newnode;
           newnode->_prev = prev;
           newnode->_next = cur;
           cur->_prev = newnode;

           return newnode;
       }

       iterator erase(iterator pos)
       {
           assert(pos != end());

           Node* cur = pos._node;
           Node* prev = cur->_prev;
           Node* next = cur->_next;
           prev->_next = next;
           next->_prev = prev;

           delete cur;

           return next;
       }

   private:
       Node* _head;
   };

//    template <class T>
//    struct ListNode
//    {
//        ListNode(const T& val = T())
//            : _prev(nullptr)
//            , _next(nullptr)
//            , _val(val)
//        {};
//        ListNode* _prev;
//        ListNode* _next;
//        T _val;
//    };
//
//    template <class T>
//    struct _list_iterator
//    {
//        typedef ListNode<T> Node;
//        typedef _list_iterator<T> iterator;
//        Node* lt;
//
//        _list_iterator(Node* x)
//            : lt(x)
//        {}
//
//        T& operator*()
//        {
//            return lt->_val;
//        }
//
//        iterator& operator++()
//        {
//            lt = lt->_next;
//            return *this;
//        }
//        iterator operator++(int)
//        {
//            iterator copy(*this);
//            lt = lt->_next;
//            return copy;
//        }
//        iterator& operator--()
//        {
//            lt = lt->_prev;
//            return *this;
//        }
//        iterator operator--(int)
//        {
//            iterator copy(*this);
//            lt = lt->_prev;
//            return copy;
//        }
//        bool operator==(const iterator& s)
//        {
//            return lt == s.lt;
//        }
//        bool operator!=(const iterator& s)
//        {
//            return !(*this == s);
//        }
//    };
//
//    template <class T>
//    class list
//    {
//    public:
//        typedef ListNode<T> Node;
//        list(const T& val = T())
//        {
//            init();
//        }
//        void init()
//        {
//            lt = new Node;
//            lt->_prev = lt;
//            lt->_next = lt;
//        }
//        typedef _list_iterator<T> iterator;
//        iterator begin()
//        {
//            return lt->_next;
//        }
//
//        iterator end()
//        {
//            return lt;
//        }
//
//        iterator insert(iterator pos, const T& val)
//        {
//           Node* newnode = new Node(val);
//           Node* prev = pos.lt->_prev;
//           newnode->_next = pos.lt;
//           newnode-> _prev = prev;
//           pos.lt->_prev = newnode;
//           prev->_next = newnode;
//           return newnode;
//        }
//        iterator erase(iterator pos)
//        {
//            Node* prev = pos.lt->_prev;
//            Node* next = pos.lt->_next;
//            prev->_next = next;
//            next->_prev = prev;
//
//            delete pos->lt;
//            return next;
//        }
//        void push_back(const T& val)
//        {
//            insert(end(), val);
//        }
//        void pop_back()
//        {
//            erase(end());
//        }
//        void push_front(const T& val)
//        {
//            insert(begin(), val);
//        }
//        void pop_front()
//        {
//            erase(begin());
//        }
//    private:
//        Node* lt;
//    };
wyd::list<int> lt;
    lt.push_back(1);
    lt.push_back(2);
    lt.push_back(3);
    lt.push_back(4);
    lt.push_back(5);
    lt.push_back(6);
    wyd::list<int>::reverse_iterator rbegin = lt.rbegin();
    while(rbegin != lt.rend())
    {
        cout << *rbegin << " ";
        ++rbegin;
    }
    cout << endl;

}
int longestOnes(vector<int>& nums, int k) 
    {
        int maxsize = 0;
        int count_zero = 0;
        int left = 0;
        int right = 0;

        while(right < nums.size())
        {
            while(right < nums.size())
            {
                if(nums[right] == 1)
                    ++right;
                else if(nums[right] == 0)
                {
                    ++count_zero;
                    if(count_zero > k)
                        break;
                    ++right;
                }
            }

            maxsize = maxsize < right - left ? right - left : maxsize;

            while(left < right) 
            {
                if(nums[left] == 1)
                    ++left;
                else if (count_zero > k)
                {
                    --count_zero;
                    ++left;
                }
                if(count_zero == k)
                {
                    ++right;
                    break;
                }
            }
        }
        return maxsize;
    }
int main()
{
    vector<int> nums = {1,1,1,0,0,0,1,1,1,1,0};
    longestOnes(nums, 2);
    return 0;
}
    ListNode* reverseBetween(ListNode* head, int m, int n) 
    {
        if(m == n)
            return head;
            
        ListNode* begin = head;
        ListNode* end = head;
        while(--m)
        {
            begin = begin->next;
        }
        while(--n)
        {
            end = end->next;
        }

        ListNode* next = begin->next;
        while(end != nullptr)
        {
            ListNode* newnode = new ListNode(begin->val);
            newnode->next = end->next;
            end->next = newnode;

            next = begin->next;s
        
            //delete node   
            begin->val = next->val;
            begin->next = next->next;
            delete next;
            if(next == end)
                end = nullptr;
            next = nullptr;
        }
        return head;
    }
};

 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 
class Solution 
{
public:
    ListNode* removeZeroSumSublists(ListNode* head) 
    {
        ListNode* cur = head;
        head = new ListNode;
        ListNode* flag = head;
        head->next = cur;

        while(cur != nullptr)
        {
            ListNode* sta = cur;
            int sum = 0;
            while(cur != nullptr)
            {
                sum += cur->val;
                cur = cur->next;
                if(sum == 0)
                {
                    head->next = cur;
                    break;
                }
            }
            if(sum != 0)
            {
                head = sta;
                cur = sta->next;
            }
        }

            return flag->next;
    }
};
 
class Solution 
{
public:
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) 
    {
        ListNode* max = l1;
        ListNode* min = l2;
        int size_1 = 0;
        int size_2 = 0;
        for(; max; ++size_1, max = max->next);
        for(; min; ++size_2, min = min->next);
        if(size_1 < size_2)
        {
            max = l2;
            min = l1;
        }
        else
        {
            max = l1;
            min = l2;
        }
        ListNode* head = max;

        while(min)
        {
            int sum = min->val + max->val;
            max->val = sum;
            if(max->val >= 10)
            {
                if(max->next)
                    max->next->val += max->val / 10;
                else
                {
                    ListNode* newnode = new ListNode(max->val / 10);
                    max->next = newnode;
                }
                max->val = max->val % 10;
            }
            max = max->next;
            min = min->next;
        }
        while(max)
        {
            if(max->val >= 10)
            {
                if(max->next)
                    max->next->val += max->val / 10;
                else
                {
                    ListNode* newnode = new ListNode(max->val / 10);
                    max->next = newnode;
                }
                max->val = max->val % 10;
            }
            max = max->next;
        }
        return head;
    }
};
class Solution 
{
public:
    int maxDepth(string s) 
    {
        int left = 0;
        int max = 0;
        for(int i = 0; i < s.size(); ++i)
        {
            if(s[i] == '(')
                ++left;
            else if(s[i] == ')')
            {
                max = max > left ? max : left;
                --left; 
            }
        }
        return max;
    }
};
#include "test.h"
#include <stack>
//namespace wyd
//{
//    //定义一个静态数组
//    template <class T, size_t N = 10>
//    class array
//    {
//    public:
//        T& operator[](size_t pos)
//        {
//            assert(pos > 0 && pos < _size);
//            return _arr[pos];
// //        }
// //
// //    private:
// //        T _arr[N];
// //        size_t _size;
// //    };
// //}
// //template <class T1, class T2>
// //bool Less(const T1& num1, const T2& num2)
// //{
// //    return num1 < num2;
// //}
// //template<>
// //bool Less(const char& ch, const int& in)
// //{
// //    return ch < in;
// //}
// class Solution
// {
// public:
//     string makeGood(string s)
//     {
//         if(s.size() < 2)
//             return s;
//         // 使用Stack来实现功能
//         stack<char> sk1;
//         stack<char> sk2;
//         int cur = s.size() - 1;
//         int next = cur - 1;
//         while(cur >= 0)
//         {
//             sk1.push(s[cur]);
//             if(((!sk1.empty()) && !sk2.empty()) && ((sk1.top() == sk2.top() + 'a' - 'A') || (sk1.top() == sk2.top() + 'A' - 'a' )))
//             {
//                 sk1.pop();
//                 sk2.pop();
//             }
//             if(next >= 0)
//             {
//                 sk2.push(s[next]);
//                 if(((!sk1.empty()) && !sk2.empty()) && ((sk1.top() == sk2.top() + 'a' - 'A') || (sk1.top() == sk2.top() + 'A' - 'a' )))
//                 {
//                     sk1.pop();
//                     sk2.pop();
//                 }
//             }
//             cur = next - 1;
//             next = cur - 1;
//         }

//         string ret;

//         while(!sk2.empty())
//         {
//             ret.push_back(sk1.top());
//             sk1.pop();
//             ret.push_back(sk2.top());
//             sk2.pop();
//         }
//         while(!sk1.empty())
//         {
//             ret.push_back(sk1.top());
//             sk1.pop();
//         }
//         return ret;
//     }
// };
// int main()
// {
//     string s = "leEeetcode";
//     Solution S;
//     S.makeGood(s);
//     return 0;
//    Less(1,2);
//    char c = '1';
//    int b = 2;
//    Less(c,b);
    // wyd::List<int> lt;
    // lt.push_back(1);
    // lt.push_back(2);
    // lt.push_back(3);
    // lt.push_back(4);
    // lt.push_back(5);
    // lt.push_front(50);
    // lt.push_back(50);
    // lt.pop_back();
    // lt.pop_front();
    // wyd::List<int>::iterator cur = lt.begin();
    // for(auto e : lt)
    // {
    //     cout << e << ' ';
    // }
    // cout << endl;
//     // return 0;
// // }
// */
// **
//  * class Father
// {
// public:
//     Father()
//     {
//         ++_count;
//     }
// protected:
//     int _a;
//     static size_t _count;
// };
// size_t Father:: _count = 0;
// class Child:public Father
// {
// public:
//     void size()
//     {
//         cout << _count << endl;
//     }
// private:
//     int _b;
// };
// */
// class Person
// {
// public:
//     Person(const char* name, const size_t& age)
//         : _name(name)
//         , _age(age)
//     {
//         cout << "Person(const char* name, const size_t& age)" << endl;
//     }
//     void Print()
//     {
//         cout << _name << "--" << _age << "--" << endl;
//     }
// protected:
//     string _name;
//     size_t _age;
// };
// class Student:public Person
// {
// public:
//     Student(const size_t& id, const size_t& age, const char* name)
//         : _id(id)
//         , Person(name, age)
//     {
//         cout << "Student(const size_t& id, const size_t& age, const char* name)" << endl;
//     }
    
// private:
//     size_t _id;
// };

// int main()
// {
//     Student s(202120060225, 18, "赵晓铭");
//     Person p("王有东", 20);
//     p.Print();
//     p = s;
//     p.Print();
//     return 0;
// }
/**
 * class A
{
public:
    A()
    {
        cout << "A()" << endl;
    }
protected:
    int _a;
};
class B:public A
{
public:
    B()
    {
        cout << "B()" << endl;
    }
protected:
    int _b;
};
class C:public B
{
public:
    C()
    {
        cout << "C()" << endl;
    }
        string str("hello world");

    string::iterator it = str.begin();
    cout << "begin->end: ";
    while(it != str.end())
    {
        cout << *it << ' ';
        ++it;
    }    
    cout << endl;

    cout << "rbegin->rend: "; 
    string::reverse_iterator rit = str.rbegin();
    while(rit != str.rend())
    {
        cout << *rit << ' ';
        ++rit;
    }
    cout << endl;

    cout << "operator[]: ";
    for(int i = 0; i < str.size(); ++i)
    {
        cout << str[i] << ' ';
    }
    cout << endl;
    return 0;
private:
    int _c;
};
#include "test.h"
//含有static成员变量的基类
class Person
{
public:
    string _name;
};
class Student:virtual public Person
{
public:
    void Print1()
    {
        cout << _name << endl;
    }
protected:
    size_t _sid;
};
class Teacher:virtual public Person
{
public:
    void Print2()
    {
        cout << _name << endl;
    }
protected:
    size_t _tid;
};
class Assistant:public Student, public Teacher
{
    // string str("Hello world");
//     cout << "str.size(): " << str.size() << endl;
//     cout << "str.capacity(): " << str.capacity() << endl;
//     cout << "str.empty(): " << str.empty() << endl;

//     str.clear();
//     cout << "str: " << str << endl;
//     cout << "str.capacity(): " << str.capacity() << endl;
    
//     str.resize(10, 'c');
//     cout << "str: " << str << endl;

//     cout << "str.capacity(): " << str.capacity() << endl;
//     str.reserve(30);
//     cout << "str.capacity(): " << str.capacity() << endl;
    // string str3(str2);
    // string str4(10, '6');
    // str2.reserve(1);
    // cout << "str1: " << str1 << endl;
    // cout << "str2: " << str2 << endl;
    // cout << "str3: " << str3 << endl;
    // cout << "str4: " << str4 << endl;
private:
    string _study;
};
#include <iostream>
#include <string>
using namespace std;

//基类
class Person
{
public:
    virtual void A()
    {
        cout << "成人——全价" << endl;   
    }
    virtual Person* ret()
    {
        cout << "virtual Person* ret()" << endl; 
        return this;
    }
    virtual ~Person()
    {
        cout << "~Person()" << endl;
    }
};

//派生类
class Student:public Person
{
public:
    virtual void A()
    {
        cout << "学生——半价" << endl;
    }
    virtual Student* ret()
    {
        cout << "virtual Student* ret()" << endl; 
        return this;
    }
    ~Student()
    {
        cout << "~Student()" << endl;
    }
    void Print() override
    {
        
    }
};

int main()
{
    Person* p1 = new Student;
    Person* p2 = new Person;
    delete p1;
    delete p2;

    return 0;
}
#include <iostream>
#include <cassert>
using namespace std;
namespace wyd
{
    //////////////////////////////////////链表节点////////////////////////////////////
    template <class T>
    struct ListNode 
    {
        typedef ListNode<T> Node;
        ListNode(const T& val = T())
            : _prev(nullptr)
            , _next(nullptr)
            , _val(val)
            {}
        Node* _prev;
        Node* _next;
        T _val; 
    };
//////////////////////////////////////iterator 指针////////////////////////////////////    
    template <class T>
    struct _list_iterator
        {
            typedef _list_iterator<T> self;
            typedef ListNode<T> Node;
            Node* it;

            _list_iterator(Node* x)
                :it(x)
            {}

            self& operator++()
            {
                it = it->_next;
                return *this;
            }

            self operator++(int) //后置++
            {
                self other = *this;
                it = it->_next;
                return other;
            }

            self& operator--()
            {
                it = it->_prev;
                return *this;
            }

            self operator--(int) //后置--
            {
                self other = *this;
                it = it->_prev;
                return other;
            }
            T& operator*()
            {
                return it->_val;
            }
            bool operator!=(const self& other)
            {
                return it != other.it;
            }
            bool operator==(const self& other)
            {
                return it == other.it;
            }

        };
    //带头双向循环链表
    template <class T>
    class List
    {  
    public:
        List()
        {
           List_Create();
        }
        List(int n, const T& value = T())
        {
            List_Create();
            while(n--)
            {
                push_back(value);
            }
        }
        void List_Create()
        {
            _head = new Node;
            _head->_next = _head;
            _head->_prev = _head;
        }
        ~List()
        {
            clear();
            delete _head;
            _head = nullptr;
        }
        void clear()
        {
            iterator cur = begin();
            while(cur != end())
            {
                cur = erase(cur);
            }
        }
        void push_back(const T& val) { insert(end(), val); }
        void push_front(const T& val) { insert(begin(), val); }

        void pop_back() { erase(--end()); }
        void pop_front() { erase(begin()); }

        typedef _list_iterator<T> iterator;
        iterator begin() { return (iterator)_head->_next; }
        iterator end() { return (iterator)_head; }

        iterator insert(iterator pos, const T& val)
        {
            Node* newnode = new Node(val);
            Node* prev = pos.it->_prev;
            newnode->_next = pos.it;
            newnode->_prev = prev;
            prev->_next = newnode;
            pos.it->_prev = newnode;
            return newnode;
        }
        iterator erase(iterator pos)
        {
            assert(pos != end());
            Node* prev = pos.it->_prev;
            Node* next = pos.it->_next;
            prev->_next = next;
            next->_prev = prev;
            delete pos.it;
            return next;
        }
        void swap(List<T>& other)
        {
            std::swap(_head, other._head);
        }
        List<T>& operator=(List<T> lt)
        {
            swap(lt);
            return *this;
        }
        size_t size()
        {
            int count = 0;
            iterator cur = begin();
            while(cur != end())
            {
                ++count;
                ++cur;
            }
            return count;
        }
        bool empty()
        {
            return begin() == end();
        }
    private:
        typedef ListNode<T> Node;
        Node* _head;
    };
}
#include <iostream>
#include <cassert>
using namespace std;
namespace bit
{
  template<class T>
  class vector
  {
  public:
    // Vector的迭代器是一个原生指针

    typedef T* iterator;
    typedef const T* const_iterator;

    iterator begin()
    {
        return _start;
    }

    iterator end()
    {
        return _finish;
    }

    const_iterator cbegin()const
    {
        return _start;
    }

    const_iterator cend() const
    {
        return _finish;
    }



    // construct and destroy

    vector()
    {}

    vector(int n, const T& value = T())
    {
        reserve(n);
        while(n--)
        {
            push_back(value);
        }
    }

    // template<class InputIterator>

    // vector(InputIterator first, InputIterator last);

    // vector(const vector<T>& v)
    // {
    //     reserve(v.capacity());
    //     memcpy(_start, v._start, v.size() * sizeof(T));
    //     _finish = _start + v.size();
    // }

    vector<T>& operator= (vector<T> v)
    {
        swap(v);
        return *this;
    }

    ~vector()
    {
        if(_start)
        {
            delete []_start;
            _start = _finish = _end_of_storage = nullptr;
        }
    }

    // capacity

    size_t size() const 
    {
        return _finish - _start; 
    }

    size_t capacity() const
    {
        return _end_of_storage - _start;
    }

    // void reserve(size_t n)
    // {
    //     if(n > capacity())
    //     {
    //         int data = size();
    //         T *new_start = new T[n];

    //         if(_start != nullptr)
    //         {
    //             memcpy(new_start, _start, size() * sizeof(T));
    //             delete []_start;
    //         }

    //         _start = new_start;
    //         _finish = _start + data;
    //         _end_of_storage = _start + n; 
    //     }
    // }

    void resize(size_t n, const T& value = T())
    {
        if(n > size())
        {
            if(n > capacity())
            {
                reserve(n);
            }
            for(int i = size(); i < n; ++i)
            {
                push_back(value);
            }
        }
        else
        {
            _finish = _start + n;
        }
    }



    ///////////////access///////////////////////////////

    T& operator[](size_t pos)
    {
        return _start[pos];
    }

    const T& operator[](size_t pos)const
    {
        return _start[pos];
    }



    ///////////////modify/////////////////////////////

    void push_back(const T& x)
    {
        size_t newcapacity = capacity() == 0 ? 4 : 2 * capacity();
        if(size() == capacity())
        {
            reserve(newcapacity);
        }
        *_finish = x;
        ++_finish;
    }

    void pop_back()
    {
        assert(size() > 0);
        --_finish;
    }

    void swap(vector<T>& v)
    {
        std::swap(_start, v._start);
        std::swap(_finish, v._finish);
        std::swap(_end_of_storage, v._end_of_storage);
    }

    iterator insert(iterator pos, const T& x)
    {
        assert(pos >= _start);
        assert(pos < _finish);

        size_t data = pos - _start;

        if(size() == capacity())
        {
            reserve(capacity() + 1);
        }

        iterator end = _finish;
        pos = _start + data; //迭代器之前指向的空间被释放了，迭代器失效了

        while(end > pos)
        {
            *end = *(end - 1);
            --end;
        }
        *pos = x;
        ++_finish;
        return pos;
    }

    iterator erase(iterator pos)
    {
        assert(size() > 0);
        assert(pos < _finish);
        while(pos < end() - 1)
        {
            *pos = *(pos + 1);
            ++pos;
        }
        --_finish;
        return pos;
    }

  private:
    iterator _start = nullptr; // 指向数据块的开始
    iterator _finish = nullptr; // 指向有效数据的尾
    iterator _end_of_storage = nullptr; // 指向存储容量的尾
  };
}
#include "reverse_iterator.h"
// 模拟链表
namespace  wyd
{
    //////////////////// list_node 节点 //////////////////
    template<class T>
    struct ListNode
    {
        ListNode(T val = T())
                : _prev(nullptr)
                , _next(nullptr)
                , _val(val)
                {}

        ListNode *_prev;
        ListNode *_next;
        T _val;
    };
    ////////////////// iterator /////////////////////
    template <class T, class Ref, class Ptr>
    struct _list_iterator
    {
        typedef ListNode<T> Node;
        typedef _list_iterator<T, Ref, Ptr> iterator;
        Node* _it;

        _list_iterator(Node* it)
            : _it(it)
        {}

        iterator& operator++()
        {
            _it = _it->_next;
            return *this;
        }
        iterator operator++(int)
        {
            iterator copy(*this);
            _it = _it->_next;
            return copy;
        }
        iterator& operator--()
        {
            _it = _it->_prev;
            return *this;
        }
        iterator operator--(int)
        {
            iterator copy(*this);
            _it = _it->_prev;
            return copy;
        }
        bool operator!=(const iterator& another)
        {
            return _it != another._it;
        }
        bool operator==(const iterator& another)
        {
            return _it == another._it;
        }
        Ref operator*()
        {
            return _it->_val;
        }
        Ptr operator->()
        {
            return &(_it->_val);
        }
    };
    ///////////////////// list 链表 ////////////////////
    template<class T>
    class List
    {
    public:
        typedef ListNode<T> Node;
        typedef _list_iterator<T, T, T*> iterator;
        typedef _list_iterator<T, const T, const T*> const_iterator;
        List()
        {
            Init();
        }
        void Init()
        {
            _lt = new Node;
            _lt->_prev = _lt;
            _lt->_next = _lt;
        }
        ~List()
        {
            clear();
            delete _lt;
        }
        void clear()
        {
            iterator cur = begin();
            while(cur != end())
            {
                cur = erase(cur);
            }
        }

        iterator begin()
        {
            return iterator(_lt->_next);
        }
        iterator end()
        {
            return iterator(_lt);
        }

        const_iterator cbeign()
        {
            return const_iterator(_lt->_next);
        }
        const_iterator cend()
        {
            return const_iterator(end());
        }

        void push_back(const T& val)
        {
            insert(end(), val);
        }
        void pop_back()
        {
            erase(--end());
        }
        void push_front(const T& val)
        {
            insert(begin(), val);
        }
        void pop_front()
        {
            erase(begin());
        }
        iterator insert(const iterator& pos, const T& val)
        {
            Node* prev = pos._it->_prev;
            Node* newnode = new Node(val);

            newnode->_next = prev->_next;
            prev->_next = newnode;
            newnode->_prev = pos._it->_prev;
            pos._it->_prev = newnode;
            return iterator(newnode);
        }
        iterator erase(iterator pos)
        {
            assert(pos != end());

            Node* prev = pos._it->_prev;
            Node* next = pos._it->_next;
            prev->_next = next;
            next->_prev = prev;
            delete pos._it;
            return iterator(next);
        }
        int size()
        {
            int count = 0;
            iterator cur = begin();
            while(cur != end())
            {
                ++count;
                ++cur;
            }
            return count;
        }
        bool empty()
        {
            return begin() == end();
        }

    private:
        Node *_lt;
    };
}
*/#include <iostream>
#include <vector>
using namespace std;
// class Person 
// {
// public:
//     virtual void Print(string name = "Person")
//     {
//         _name = name;
//         cout << "virtual void Print(string name = ""Person"")" << endl;
//         cout << _name << endl;
//     }
//     virtual ~Person()
//     {
//         cout << "~Person()" << endl;
//     }
// protected:
//     string _name;
// };
// class Student:public Person
// {
// public:
//     virtual void Print(string name = "Student")
//     {
//         _name = name;
//         cout << "virtual void Print(string name = ""Student"")" << endl;
//         cout << _name << endl;
//     }
//     virtual ~Student()
//     {
//         cout << "~Student()" << endl;
//     }
// private:
//     size_t _id;
// };
// class A
// {
// public:
//     virtual void Print()
//     {
//         cout << "virtual void Print()" << endl;
//     }
// private:
//     int _a;
// };
// class Car
// {
// public:
//     virtual void Drive() = 0;
//     virtual ~Car()
//     {
//         cout << "~Car()" << endl;
//     }
// };
// class BMN:public Car
// {
// public:
//     void Drive()
//     {
//         cout << "BMN" << endl;
//     }
//     ~BMN()
//     {
//         cout << "~BMN()" << endl;
//     }
// };
//     int minOperations(vector<int>& nums, int x) 
//     {
//         int left = 0;
//         int right = 0;
        
//         int sum = 0;
//         for(auto e : nums)
//             sum += e;

//         int target = sum - x;
//         int total = 0;
//         int count = 0;

//         while(left < nums.size())
//         {
//             if(total <= target)
//                 total += nums[right++];
//             else if(total > target)
//                 total -= nums[left++];

//             if(total == target)
//                 count = count > (right - left) ? count : (right - left);
//             if(right == nums.size() && total <= target)
//                 break;
//         }
//         if(count)
//             return nums.size() - count;
//         return -1;
//     }
// int main()
// {
//     vector<int> v;
//     v.push_back(8828);
//     v.push_back(9581);
//     v.push_back(49);
//     v.push_back(9818);
//     v.push_back(9974);
//     v.push_back(9869);
//     v.push_back(9991);
//     v.push_back(10000);
//     v.push_back(10000);
//     v.push_back(10000);
//     v.push_back(9999);
//     v.push_back(9993);
//     v.push_back(9904);
//     v.push_back(8819);
//     v.push_back(1231);
//     v.push_back(6309);
//     minOperations(v, 134365);
//     return 0;
// }
/**
 * #include <iostream>
#include <vector>
using namespace std;
// class Person 
// {
// public:
//     virtual void Print(string name = "Person")
//     {
//         _name = name;
//         cout << "virtual void Print(string name = ""Person"")" << endl;
//         cout << _name << endl;
//     }
//     virtual ~Person()
//     {
//         cout << "~Person()" << endl;
//     }
// protected:
//     string _name;
// };
// class Student:public Person
// {
// public:
//     virtual void Print(string name = "Student")
//     {
//         _name = name;
//         cout << "virtual void Print(string name = ""Student"")" << endl;
//         cout << _name << endl;
//     }
//     virtual ~Student()
//     {
//         cout << "~Student()" << endl;
//     }
// private:
//     size_t _id;
// };
// class A
// {
// public:
//     virtual void Print()
//     {
//         cout << "virtual void Print()" << endl;
//     }
// private:
//     int _a;
// };
// class Car
// {
// public:
//     virtual void Drive() = 0;
//     virtual ~Car()
//     {
//         cout << "~Car()" << endl;
//     }
// };
// class BMN:public Car
// {
// public:
//     void Drive()
//     {
//         cout << "BMN" << endl;
//     }
//     ~BMN()
//     {
//         cout << "~BMN()" << endl;
//     }
// };
    // int minOperations(vector<int>& nums, int x) 
    // {
    //     int left = 0;
    //     int right = 0;
        
    //     int sum = 0;
    //     for(auto e : nums)
    //         sum += e;

    //     int target = sum - x;
    //     int total = 0;
    //     int count = 0;

    //     while(left < nums.size())
    //     {
    //         if(total <= target)
    //             total += nums[right++];
    //         else if(total > target)
    //             total -= nums[left++];

    //         if(total == target)
    //             count = count > (right - left) ? count : (right - left);
    //         if(right == nums.size() && total <= target)
    //             break;
    //     }
    //     if(count)
    //         return nums.size() - count;
    //     return -1;
    // }
class Base
{
public:
    virtual void Fun1()
    {
        cout << " Base::Fun1()" << endl;
    }
    virtual void Fun2()
    {
        cout << "Base::Fun2()" << endl;
    }
    void Fun3()
    {
        cout << "Base::Fun3()" << endl;
    }
protected:
    int _b;
};
class Derive:public Base
{
public:
    virtual void Fun1()
    {
        cout << "Derive::Fun1()" << endl;
    }
private:
    int _d;
};
int main()
{
    int a = 0;
    cin >> a;
    Base b;
    cout << sizeof(b) << endl;
    Derive d;
    return 0;
}
//#include <iostream>
//using namespace std;
//class Person
//{
//public:
//    void Print()
//    {
//        cout << "name:" << _name << endl;
//        cout << "age:" << _age << endl;
//    }
//protected:
//    string _name = "peter"; // 姓名
//    int _age = 18; // 年龄
//};
//class Student : public Person
//{
//public:
//    void Print()
//    {
//        cout << "Student::Print()" << endl;
//    }
//protected:
//    int _stu_id; // 学号
//};
//class Teacher : public Person
//{
//protected:
//    int _jobid; // 工号
//};
//int main()
//{
//    Student s;
//    s.Print();
//    return 0;
//}
//class Base
//{
//public:
//    virtual void Func1()
//    {
//        cout << "Base::Func1()" << endl;
//    }
//
//private:
//    int _b = 1;
//};
//class A
//{
//public:
//    A()
//        :m_iVal(0)
//    {
//        test();
//    }
//    virtual void func()
//    {
//        cout << m_iVal << " ";
//    }
//    void test()
//    {
//        func();
//    }
//public:
//    int m_iVal;
//};
//class B : public A
//{
//public:
//    B()
//    {
//        test();
//    }
//    virtual void func()
//    {
//        ++m_iVal;
//        cout << m_iVal << " ";
//    }
//};
//class Base
//{
//public :
//    virtual void func1() { cout<<"Base::func1" <<endl;}
//    virtual void func2() {cout<<"Base::func2" <<endl;}
//private :
//    int a;
//};
//class Derive :public Base
//{
//public :
//    virtual void func1() {cout<<"Derive::func1" <<endl;}
//    virtual void func3() {cout<<"Derive::func3" <<endl;}
//    virtual void func4() {cout<<"Derive::func4" <<endl;}
//private :
//    int b;
//};
//int main()
//{
//    cout << sizeof(Base) << endl;
//    cout << sizeof(Derive) << endl;
//    return 0;
//}
//class Base {
//public :
//    virtual void func1() { cout<<"Base::func1" <<endl;}
//    virtual void func2() {cout<<"Base::func2" <<endl;}
//private :
//    int a;
//};
//class Derive :public Base {
//public :
//    virtual void func1() {cout<<"Derive::func1" <<endl;}
//    virtual void func3() {cout<<"Derive::func3" <<endl;}
//    virtual void func4() {cout<<"Derive::func4" <<endl;}
//private :
//    int b;
//};
//typedef void(*VFPTR) ();
//void PrintVTable(VFPTR vTable[])
//{
//// 依次取虚表中的虚函数指针打印并调用。调用就可以看出存的是哪个函数
//    cout << " 虚表地址>" << vTable << endl;
//    for (int i = 0; vTable[i] != nullptr; ++i)
//    {
//        printf(" 第%d个虚函数地址 :0X%x,->", i, vTable[i]);
//        VFPTR f = vTable[i];
//        f();
//    }
//    cout << endl;
//}
//int main()
//{
//    Base b;
//    Derive d;
//// 思路：取出b、d对象的头4bytes，就是虚表的指针，前面我们说了虚函数表本质是一个存虚函数
////    指针的指针数组，这个数组最后面放了一个nullptr
//// 1.先取b的地址，强转成一个int*的指针
//// 2.再解引用取值，就取到了b对象头4bytes的值，这个值就是指向虚表的指针
//// 3.再强转成VFPTR*，因为虚表就是一个存VFPTR类型(虚函数指针类型)的数组。
//// 4.虚表指针传递给PrintVTable进行打印虚表
//// 5.需要说明的是这个打印虚表的代码经常会崩溃，因为编译器有时对虚表的处理不干净，虚表最
////    后面没有放nullptr，导致越界，这是编译器的问题。我们只需要点目录栏的-生成-清理解决方案，再
////    编译就好了。
//    VFPTR* vTableb = (VFPTR*)(*(int*)&b);
//    PrintVTable(vTableb);
//    VFPTR* vTabled = (VFPTR*)(*(int*)&d);
//    PrintVTable(vTabled);
//    return 0;
//}
//class Base
//{
//public:
//    virtual void Func1()
//    {
//        cout << "Base::Func1()" << endl;
//    }
//    virtual void Func2()
//    {
//        cout << "Base::Func2()" << endl;
//    }
//    void Func3()
//    {
//        cout << "Base::Func3()" << endl;
//    }
//private:
//    int _b = 1;
//};
//class Derive : public Base
//{
//public:
//    virtual void Func1()
//    {
//        cout << "Derive::Func1()" << endl;
//    }
//private:
//    int _d = 2;
//};
//class A
//{
//public:
//    virtual void x()
//    {
//        cout << "A::x()" << endl;
//    }
//};
//class B:public A
//{
//public:
//    virtual void x()
//    {
//        cout << "B::x()" << endl;
//    }
//};
//int main()
//{
//    B b;
//    b.x();
//    Base b;
//    Derive d;
//    cout << sizeof(Derive) << endl;
//    return 0;
//}
//class Base
//{
//public:
//    virtual void Func1()
//    {
//        cout << "Base::Func1()" << endl;
//    }
//    virtual void Func2()
//    {
//        cout << "Base::Func2()" << endl;
//    }
//    void Func3()
//    {
//        cout << "Base::Func3()" << endl;
//    }
//private:
//    int _b = 1;
//};
//class Derive : public Base
//{
//public:
//    virtual void Func1()
//    {
//    cout << "Derive::Func1()" << endl;
//    }
//        private:
//        int _d = 2;
//    };
//class A
//{
//public:
//    void Print()
//    {
//        cout << "Print()" << endl;
//    }
//    virtual void Base()
//    {
//        cout << "A::Base()" << endl;
//    }
//    virtual ~A()
//    {
//        cout << "~A()" << endl;
//    }
//protected:
//    int _a;
//};
//class B:public A
//{
//public:
//    virtual void Base()
//    {
//        cout << "B::Base()" << endl;
//    }
//    virtual ~B()
//    {
//        cout << "~B()" << endl;
//    }
//private:
//    int _b;
//};
//int main()
//{
//    B b;
//    b.Print(); //实现继承，继承的是基类的函数实现
//    A* a = new B;
//    a->Base();
////    Base b;
////    Derive d;
//    return 0;
//}
//class Solution
//{
//public:
//    void Tree2StrR(string& str, TreeNode* root)
//    {
//        if(root == nullptr)
//            return;
//
//        string num;
//        int n = abs(root->val);
//        if(n == 0)
//        {
//            num += '0';
//        }
//        else
//        {
//            while(n)
//            {
//                num.insert(num.begin(), n % 10 + '0');
//                n /= 10;
//            }
//            if(root->val < 0)
//                num.insert(num.begin(), '-');
//        }
//        str += num;
//
//        if(root->left == nullptr && root->right == nullptr)
//            return;
//
//        str.push_back('(');
//        Tree2StrR(str, root->left);
//        str.push_back(')');
//
//        str.push_back('(');
//        Tree2StrR(str, root->right);
//        str.push_back(')');
//    }
//    string tree2str(TreeNode* root)
//    {
//        string str;
//        Tree2StrR(str, root);
//        for(int i = 0; i < str.size() - 1;)
//        {
//            if(str[i] == '(' && str[i + 1] == ')' && str[i - 1] == ')')
//            {
//                str.erase(i, 2);
//            }
//            else
//                ++i;
//        }
//        return str;
//    }
//};
//
// * Definition for a binary tree node.
// * struct TreeNode {
// *     int val;
// *     TreeNode *left;
// *     TreeNode *right;
// *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
// * };
//
//class Solution
//{
//public:
//    bool Find_Rood(stack<TreeNode*>& sk, TreeNode* root, TreeNode* find)
//    {
//        if(root == nullptr)
//            return false;
//
//        sk.push(root);
//        if(root != find)
//        {
//            if(Find_Rood(sk, root->left, find) || Find_Rood(sk, root->right, find))
//            {
//                return true;
//            }
//            else
//            {
//                sk.pop();
//            }
//        }
//        else
//        {
//            return true;
//        }
//        return false;
//    }
//    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q)
//    {
//        stack<TreeNode*> sp;
//        stack<TreeNode*> sq;
//        Find_Rood(sp, root, p);
//        Find_Rood(sq, root, q);
//
//        while(sp.size() != sq.size())
//        {
//            if(sp.size() > sq.size())
//                sp.pop();
//            else
//                sq.pop();
//        }
//
//        while(!sp.empty())
//        {
//            if(sp.top() == sq.top())
//                return sp.top();
//            else
//            {
//                sp.pop();
//                sq.pop();
//            }
//        }
//
//        assert(false);
//        return nullptr;
//    }
//};
// class Solution
// {
// public:
// bool Find(TreeNode* root, TreeNode* find)
// {
//     if(root == nullptr)
//         return false;
//     if(root == find)
//         return true;
//     return Find(root->left, find) || Find(root->right, find);
// }
//     TreeNode* Find_Parent(TreeNode* root, TreeNode* p, TreeNode* q)
//     {
//         TreeNode* cur = root;
//         while(cur)
//         {
//             if(Find(cur->left, p) && Find(cur->left, q)) //p和q都在左子树
//                 cur = cur->left;
//             else if(Find(cur->right, p) && Find(cur->right, q)) //p和q都在右子树
//                 cur = cur->right;
//             if((Find(cur->left, p) && Find(cur->right, q)) || (Find(cur->left, q) && Find(cur->right, p))) //p和q分别在两个子树
//                 return cur;
//         }
//         return nullptr;
//     }
//     TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q)
//     {
//         //q在p为根的树中，最近祖先为p
//         if(Find(p, q))
//             return p;
//         else //q不在p为根的树中
//         {
//             if(Find(q, p)) //p在q为根的树中，最近祖先为q
//                 return q;
//             else
//                 return Find_Parent(root, p, q);
//         }
//     }
// };
//class Solution
//{
//public:
//public:
//    void InOrder(TreeNode* cur, TreeNode*& prev)
//    {
//        if(cur == nullptr)
//            return ;
//        InOrder(cur->left, prev);
//        cur->left = prev;
//        if(prev)
//            prev->right = cur;
//        prev = cur;
//        InOrder(cur->right, prev);
//    }
//    TreeNode* Convert(TreeNode* root)
//    {
//        if(root == nullptr)
//        {
//            return root;
//        }
//        TreeNode* prev = nullptr;
//        TreeNode* cur = root;
//        while(cur->left)
//        {
//            cur = cur->left;
//        }
//        InOrder(root, prev);
//        return cur;
//    }
//};
//class Solution
//{
//public:
//    void BinaryTree(TreeNode*& root, vector<int> preorder, vector<int> inorder)
//    {
//        if(preorder.size() == 0)
//            return;
//        if(inorder.size() == 0)
//            return;
//
//        root = new TreeNode(preorder[0]);
//        vector<int> preleft;
//        vector<int> inleft;
//        vector<int> preright;
//        vector<int> inright;
//
//        int i = 0;
//        int j = 1;
//
//        for(; inorder[i] != preorder[0]; ++i)
//        {
//            inleft.push_back(inorder[i]);
//        }
//        for(++i; i < inorder.size(); ++i)
//        {
//            inright.push_back(inorder[i]);
//        }
//        for(; j < inleft.size() + 1; ++j)
//        {
//            preleft.push_back(preorder[j]);
//        }
//        for(; j < preorder.size(); ++j)
//        {
//            preright.push_back(preorder[j]);
//        }
//
//        BinaryTree(root->left, preleft, inleft);
//        BinaryTree(root->right, preright, inright);
//    }
//    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder)
//    {
//        TreeNode* root;
//        BinaryTree(root, preorder, inorder);
//        return root;
//    }
//};
//#include "fun.h"
//int main()
//{
//    wyd::BSTree<string> tree;
//    tree.InSert("table");
//    tree.InSert("watch");
//    tree.InSert("person");
//    tree.InSert("man");
//    tree.InSert("woman");
//    tree.InSert("car");
//    string word;
//    while(cin >> word)
//    {
//        if(tree.find(word))
//            cout << "correct" << endl;
//        else
//            cout << "error" << endl;
//    }
//    return 0;
//}
//////////////////////////////////////////////复印机状态问题
//#include <iostream>
//using namespace std;
//#define IDLE 0 // 闲置状态
//#define COPY 1 //复印状态
//#define HF 2   // 缺纸状态
//#define PJ 3   //卡纸状态
//
//class Copier
//{
//public:
//    //检测状态
//    void State()
//    {
//        switch (_state)
//        {
//            case IDLE:
//                cout << "闲置状态" << endl;
//                break;
//            case COPY:
//                cout << "复印状态" << endl;
//                break;
//            case HF:
//                cout << "缺纸状态" << endl;
//                break;
//            case PJ:
//                cout << "卡纸状态" << endl;
//                break;
//            default:
//                cout << "状态异常" << endl;
//                break;
//        }
//    }
//    //复印
//    void Copy()
//    {
//        //不缺纸
//        if(_paper_size > 0)
//        {
//            _state = COPY;
//            --_paper_size;
//            if(_paper_jam == PJ)
//            {
//                Excluded();
//            }
//            _state = IDLE;
//        }
//        //缺纸
//        else
//        {
//            _state = HF;
//            Fill();
//        }
//    }
//    //填纸
//    void Fill()
//    {
//        _paper_size = 100;
//        _state = IDLE;
//    }
//    //解决卡纸
//    void Excluded()
//    {
//        _paper_jam = IDLE;
//    }
//
//private:
//    int _state = IDLE; //复印机状态
//    int _paper_size = 0; //纸张
//    int _paper_jam = IDLE;
//
//};
//int main()
//{
//
//    return 0;
//}
/**
 * class Solution
{
public:
    TreeNode* Build(vector<int>& preorder, vector<int>& inorder, int& root_val, int left, int right)
    {
        if(left > right)
            return nullptr;
        if(root_val >= preorder.size())
            return nullptr;

        int parent = right;
        int parent2 = left;
        TreeNode* root = new TreeNode(preorder[root_val++]);

        int cur = 0;
        for(; inorder[cur] != root->val; ++cur);

        root->left = Build(preorder, inorder, root_val, parent2, cur - 1);
        root->right = Build(preorder, inorder, root_val, cur + 1, parent);

        return root;
    }
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder)
    {
        int root_val = 0;
        return Build(preorder, inorder, root_val, 0, inorder.size() - 1);
    }
};
#include <iostream>
#include <string>
using namespace std;
//实现一棵二叉搜索树binary search tree
//首先要实现一棵树的节点BSTreeNode
namespace wyd
{
template<class K>
struct BSTreeNode
{
    BSTreeNode(const K &key)
            : _left(nullptr)
            , _right(nullptr)
            , _key(key)
    {}

    typedef BSTreeNode<K> Node;
    Node *_left;
    Node *_right;
    K _key;
};

template<class K>
class BSTree
{
    typedef BSTreeNode<K> Node;
public:

    //查找二叉树的某个节点
    bool find(const K &key)
    {
        Node *cur = _root;
        while (cur)
        {
            if (cur->_key > key)
            {
                cur = cur->_left;
            }
            else if (cur->_key < key)
            {
                cur = cur->_right;
            }
            else
            {
                return true;
            }
        }
        return false;
    }

    //递归查找
    bool findR(const K& key)
    {
        return FindR(_root, key);

    }

    //中序遍历
    void InOrder()
    {
        InOrderR(_root);
        cout << endl;
    }

    //插入操作
    bool InSert(const K &key)
    {
        Node *newnode = new Node(key);
        if (_root == nullptr)
        {
            _root = newnode;
            return true;
        }

        Node *cur = _root;
        Node *parent = nullptr;
        while (cur)
        {
            if (cur->_key > key)
            {
                parent = cur;
                cur = cur->_left;
            }
            else if (cur->_key < key)
            {
                parent = cur;
                cur = cur->_right;
            }
            else
            {
                return false;
            }
        }
        if (parent->_key < key)
        {
            parent->_right = newnode;
        }
        else
        {
            parent->_left = newnode;
        }
        return true;
    }
    //insertR插入递归版本
    bool insertR(const K& key)
    {
        return InsertR(_root, key);
    }

    //删除操作递归版本
    bool eraseR(const K& key)
    {
        return EraseR(_root, key);
    }
private:
    Node *_root = nullptr;

    //删除操作递归版本
    bool EraseR(Node*& cur, const K& key)
    {
        if(cur == nullptr)
        {
            return false;
        }
        if(cur->_key > key)
        {
            return EraseR(cur->_left, key);
        }
        else if(cur->_key < key)
        {
            return EraseR(cur->_right, key);
        }
        else
        {
            Node* dele = cur;
            if(cur->_left == nullptr)
            {
                cur = cur->_right;
            }
            else if(cur->_right == nullptr)
            {
                cur = cur->_left;
            }
            else
            {
                dele = cur->_right;
                Node* parent = nullptr;
                while(dele->_left)
                {
                    parent = dele;
                    dele = dele->_left;
                }
                cur->_key = dele->_key;
                parent->_left = dele->_right;
            }
            delete dele;
            return true;
        }
    }
    //insert插入递归版本
    bool InsertR(Node*& cur, const K& key)
    {
        if(cur == nullptr)
        {
            cur = new Node(key);
            return true;
        }
        if(cur->_key > key)
        {
            return InsertR(cur->_left, key);
        }
        else if(cur->_key < key)
        {
            return InsertR(cur->_right, key);
        }
        else
        {
            return false;
        }

    }
    //find查找递归版本
    bool FindR(Node* cur, const K& key)
    {
        if(cur == nullptr)
            return false;
        if(cur->_key > key)
        {
            return FindR(cur->_left, key);
        }
        else if(cur->_key < key)
        {
            return FindR(cur->_right, key);
        }
        else
        {
            return true;
        }
    }
    //中序遍历递归版本
    void InOrderR(Node *cur)
    {
        if (cur == nullptr)
            return;
        InOrderR(cur->_left);
        cout << cur->_key << " ";
        InOrderR(cur->_right);

    }
};

}~
class Solution 
{
public:
    TreeNode* Build(vector<int>& inorder, vector<int>& postorder, int& root_val, int left, int right)
    {
        if(left > right)
            return nullptr;
        if(root_val < 0)
            return nullptr;

        int Right = right;
        int Left = left;
        
        TreeNode* root = new TreeNode(postorder[root_val--]);

        int cur = 0;
        for(; inorder[cur] != root->val; ++cur);

        root->right = Build(inorder, postorder, root_val, cur + 1, Right);
        root->left = Build(inorder, postorder, root_val, Left, cur - 1);

        return root;
    }

    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) 
    {
        int root_val = postorder.size() - 1;
        return Build(inorder, postorder, root_val, 0, inorder.size() - 1);
    }
};
class Solution 
{
public:
    vector<int> postorderTraversal(TreeNode* root) 
    {
        vector<int> ret;
        stack<TreeNode*> skt;
        TreeNode* cur = root;
        TreeNode* flag = nullptr;

        while(cur || !skt.empty())
        {

            //把它们分为两部分
            //1:根结点与左孩子
            //2:根的右子树
            while(cur)
            {
                skt.push(cur);
                cur = cur->left;
            }

            TreeNode* top = skt.top();
            
            //1. 右孩子为nullptr；2. 右孩子访问过；
            if(top->right == nullptr || flag == top->right )
            {
                ret.push_back(top->val);
                flag = top;
                skt.pop();
            }
            else
            {
                cur = top->right;
            }
        }
        return ret;
    }
};
class Solution 
{
public:
    bool Find(vector<TreeNode*>& flag, TreeNode*& tail)
    {
        for(auto e : flag)
        {
            if(tail == e)
                return true;
        }
        return false;
    }
    int sumRootToLeaf(TreeNode* root) 
    {
        TreeNode* cur = root; //遍历根结点和左孩子
        vector<TreeNode*> flag;//做标记，这里必须用vector来存，因为存在走过多个节点

        int ret = 0; //结果

        vector<TreeNode*> vT; 

        while(cur || !vT.empty())
        {
            while(cur)
            {
                vT.push_back(cur);
                cur = cur->left;
            }

            TreeNode* tail = vT[vT.size() - 1];

            //右孩子不在，左孩子在
            if(tail->right == nullptr && tail->left != nullptr)
            {
                vT.pop_back();
            }
            //为叶节点，证明该路径结束
            else if(tail->right == nullptr && tail->left == nullptr)
            {
                int i = 0;
                for(auto it = vT.rbegin(); it != vT.rend(); ++it, ++i)
                {
                    ret += (*it)->val * pow(2, i);
                }
                vT.pop_back();
            }
            //右孩子在，路径没走过
            else if(tail->right != nullptr && !Find(flag, tail))
            {
                flag.push_back(tail);
                cur = tail->right;
            }
            //右孩子在，路径走过了
            else if(Find(flag, tail))
            {
                vT.pop_back();
            }
            else;
        }
        return ret;
    }
};
class Solution 
{
public:
    int Computing(TreeNode* root, int& ret)
    {
        if(root == nullptr)
            return 0;

        //记录左子树和右子树的和
        int left_sum = Computing(root->left, ret);
        int right_sum = Computing(root->right, ret);

        //做差
        ret += abs(left_sum - right_sum);

        //重点：返回节点的左子树节点或者右子树节点之和
        return left_sum + right_sum + root->val;
    }
    int findTilt(TreeNode* root) 
    {
        int ret = 0;
        Computing(root, ret);
        return ret;
    }
};
class Solution 
{
public:
    bool isEvenOddTree(TreeNode* root) 
    {
        //层序遍历，严格判断单调性，奇偶性
        pair<int, vector<TreeNode*>> p;

        p.first = 0;
        p.second.push_back(root);

        while(!p.second.empty())
        {
            //先看层数是奇数还是偶数
            if(p.first % 2 == 0) //层数为偶数，1：节点都为奇数，2：满足严格递增
            {
                for(int i = 0; i < p.second.size(); ++i)
                {
                    //若为偶数，则不是奇偶树
                    if(p.second[i]->val % 2 == 0)
                        return false;
                    //若不是严格递增，则不是奇偶树
                    if(i < p.second.size() - 1 && p.second[i]->val >= p.second[i + 1]->val)
                    {
                        return false;
                    }
                }
            }
            else //层数为奇数，1：节点都为偶数，2：满足严格递减
            {
                for(int i = 0; i < p.second.size(); ++i)
                {
                    //若为奇数，则不是奇偶树
                    if(p.second[i]->val % 2 != 0)
                        return false;
                    //若不是严格递减，则不是奇偶树
                    if(i < p.second.size() - 1 && p.second[i]->val <= p.second[i + 1]->val)
                    {
                        return false;
                    }
                }
            }
            //判断结束，本层满足，开始遍历下一层
            ++p.first;
            int size = p.second.size();
            for(int i = 0; i < size; ++i)
            {
                if(p.second[i]->left)
                    p.second.push_back(p.second[i]->left);
                if(p.second[i]->right)
                    p.second.push_back(p.second[i]->right);
            }
            p.second.erase(p.second.begin(), p.second.begin() + size);
        }
        return true;
    }
};
////声明一个AVL树的节点
//template <class K, class V>
//struct AVLTreeNode
//{
//    AVLTreeNode(const pair<K, V>& kv)
//        : _left(nullptr)
//        , _right(nullptr)
//        , _parent(nullptr)
//        , _bf(0)
//        , _kv(kv)
//    {}
//    typedef AVLTreeNode<K, V> Node;
//    Node* _left;
//    Node* _right;
//    Node* _parent;
//    int _bf;
//    pair<K, V> _kv;
//};
//
////声明AVL树
//template <class K, class V>
//class AVLTree
//{
//public:
//    typedef AVLTreeNode<K, V> Node;
//    bool Insert(const pair<K, V>& kv)
//    {
//        //空树
//        if(_root == nullptr)
//        {
//            _root = new Node(kv);
//            return true;
//        }
//        //不为空树
//        else
//        {
//            Node* cur = _root;
//            Node* par = cur;
//
//            while(cur)
//            {
//                if(cur->_kv.first > kv.first)
//                {
//                    par = cur;
//                    cur = cur->_right;
//                }
//                else if(cur->_kv.first < kv.first)
//                {
//                    par = cur;
//                    cur = cur->_left;
//                }
//                else
//                    return false;
//            }
//
//            Node* newnode = new Node(kv);
//            if(par->_kv > newnode->_kv)
//            {
//                par->_left = newnode;
//            }
//            else
//            {
//                par->_right = newnode;
//            }
//
//            newnode->_parent = par;
//
//            while(par)
//            {
//                //在右树中插入，默认平衡因子_bf = 右树 - 左树
//                if(newnode == par->_right)
//                    par->_bf++;
//                else if(newnode == par->_left)
//                    par->_bf--;
//
//                if(par->_bf == 0)
//                    break;
//                else if(par->_bf == 1 || par->_bf == -1)
//                {
//                    newnode = par;
//                    par = par->_parent;
//                }
//                else if(par->_bf == 2 || par->_bf == -2)
//                {
//                    //旋转
//                    if(par->_bf == 2 && newnode->_bf == 1)
//                    {
//                        //左单旋
//                        RotateL(par);
//                    }
//                    else if(par->_bf == -2 && newnode->_bf == -1)
//                    {
//                        //右单旋
//                        RotateR(par);
//                    }
//                }
//                else
//                {
//                    assert(false);
//                }
//
//            }
//            return true;
//        }
//
//    }
//
//    //右单旋
//    void RotateR(Node* parent)
//    {
//        Node* pL = parent->_left;
//        Node* pLR = pL->_right;
//
//        parent->_left = pLR;
//        pL->_right = parent;
//        if(pLR)
//            pLR->_parent = parent;
//        Node* pparent = parent->_parent;
//        parent->_parent = pL;
//
//        if(parent == _root)
//        {
//            _root = pL;
//            pL->_parent = nullptr;
//        }
//        else
//        {
//            if(pparent->_left == parent)
//                pparent->_left = pL;
//            else
//                pparent->_right = pL;
//            pL->_parent = pparent;
//        }
//
//        parent->_bf = 0;
//        pL->_bf = 0;
//    }
//    //左单旋
//    void RotateL(Node* parent)
//    {
//        Node* pr = parent->_right;
//        Node* prl = pr->_left;
//
//        parent->_right = prl;
//        if(prl)
//            prl->_parent = parent;
//        pr->_left = parent;
//
//        Node* pparent = parent->_parent;
//
//        parent->_parent = pr;
//
//        if(parent == _root)
//        {
//            _root = pr;
//            pr->_parent = nullptr;
//        }
//        else
//        {
//            if(pparent->_left == parent)
//                pparent->_left = pr;
//            else
//                pparent->_right = pr;
//            pr->_parent = pparent;
//        }
//
//        parent->_bf = 0;
//        pr->_bf = 0;
//
//    }
//private:
//    Node* _root = nullptr;
//};
class Solution 
{
public:
    vector<int> searchRange(vector<int>& nums, int target) 
    {
        vector<int> ret;
        int left1 = 0, left2 = 0;
        int right1 = nums.size() - 1, right2 = nums.size() - 1;
        int begin = -1;
        int end = -1;
        while(left1 <= right1)
        {
            int mid1 = left1 + (right1 - left1) / 2;
            if(nums[mid1] > target)
            {
                right1 = mid1 - 1;
            }
            else if(nums[mid1] < target)
            {
                left1 = mid1 + 1;
            }
            else //记录最前面的mid，再去mid前面找，若没找到，最后记录的就是最开始的
            {
                begin = mid1;
                right1 = mid1 - 1;
            }
        }
        while(left2 <= right2)
        {
            int mid2 = left2 + (right2 - left2) / 2;
            if(nums[mid2] > target)
            {
                right2 = mid2 - 1;
            }
            else if(nums[mid2] < target)
            {
                left2 = mid2 + 1;
            }
            else //记录最后面的mid，再去mid后面找，若没找到，最后记录的就是最末尾的
            {
                end = mid2;
                left2 = mid2 + 1;
            }
        }

        ret.push_back(begin);
        ret.push_back(end);
        return ret;
    }
};
//#include <iostream>
//#include <set>
//#include <map>
//#include <array>
//using namespace std;
//void test1()
//{
//    set<int> s;
////    s.insert(10);
////    s.insert(-1);
////    s.insert(9);
////    s.insert(4);
////    s.insert(2);
////    s.insert(3);
////    for(auto e : s)
////    {
////        cout << e << " ";
////    }
////    cout << endl;
////
////    auto begin = s.lower_bound(1);
////    auto end = s.upper_bound(7);
////    s.erase(begin, end);
////    for(auto e : s)
////    {
////        cout << e << " ";
////    }
////    cout << endl;
////
////    cout << *end << endl;
////    while(begin != end)
////    {
////        cout << *begin << " ";
////        ++begin;
////    }
////    cout << endl;
////    auto pos = s.find(6);
////    s.erase(pos);
////    if(pos != s.end())
////    {
////        cout << "找到了" << endl;
////        s.erase(pos);
////    }
////    else
////    {
////        cout << "没找到" << endl;
////    }
////    for(auto e : s)
////    {
////        cout << e << " ";
////    }
////    cout << endl;
////    auto it = s.begin();
////    while(it != s.end())
////    {
////        cout << *it << " ";
////        ++it;
////    }
////    cout << endl;
//}
//void test2()
//{
//    map<string, string> m;
//    m.insert(pair<string, string>("sort", "排序"));
//    m.insert({"apple", "苹果"});
//    m.insert(make_pair("banana", "香蕉"));
//    auto begin = m.begin();
//    cout << begin->first << endl;
////    for(const auto& e : m)
////    {
////        cout << e.first << ":" << e.second << endl;
////    }
//}
//void test3()
//{
//    multiset<int> s;
//    s.insert(3);
//    s.insert(5);
//    s.insert(2);
//    s.insert(1);
//    s.insert(4);
//    s.insert(3);
//
//    for(auto e : s)
//    {
//        cout << e << " ";
//    }
//    cout << endl;
//    cout << s.count(3) << endl;
//}
//void test4()
//{
//    map<string, string> m;
//    m["sort"];
//    pair<map<string, string>::iterator, bool> e = m.insert(make_pair("sort", "排序"));
//    e.first->second = "排序";
////    if(e.second)
////        cout << "插入成功，是第一次出现" << endl;
////    else
////        cout << "false" << endl;
////    m["apple"] = "苹果";
////    m["sort"] = "sort";
//
//    for(const auto& it : m)
//    {
//        cout << it.first << ":" << it.second << endl;
//    }
//}
//vector<string> topKFrequent(vector<string>& words, int k)
//{
//    ///可以使用map，first存放单词，second存放单词出现的次数
//    map<string, int> m;
//    int i = 0;
//    for(i = 0; i < words.size(); ++i)
//    {
//        ++m[words[i]];
//    }
//    ///经过map构建后，可以算出每个出现的次数；
//    /// i->2, love->2, le->1, co->1
//
//    ///定义一个vector，每个元素存放两个位置
//    vector<pair<string, int>> vp;
//    i = 0;
//    for(auto it = m.begin(); it != m.end(); ++it, ++i)
//    {
//        vp.push_back(make_pair(it->first, it->second));
//    }
//    ///先通过出现次数排序
//
////    return ret;
//}
//vector<string> topKFrequent(vector<string>& words, int k)
//{
//    ///可以使用map，first存放单词，second存放单词出现的次数
//    map<string, int> m;
//    int i = 0;
//    for(i = 0; i < words.size(); ++i)
//    {
//        ++m[words[i]];
//    }
//    ///经过map构建后，可以算出每个出现的次数；
//    /// i->2, love->2, le->1, co->1
//    ///构建一个静态数组，元素分别为出现的次数，和出现该次数的所有字符串
//    array<pair<int, vector<string>>, 501> vp;
//    i = 0;
//    for(auto it = m.begin(); it != m.end(); ++it, ++i)
//    {
//        vp[it->second].first = it->second;
//        vp[it->second].second.push_back(it->first);
//    }
//    // [ [0, [""]], [1, ["co", "le"]], [2, ["i", "love"]] ]
//     ///排序一样次数的字符串
//     unsigned long count = 0;
//     for(i = 1; count < words.size(); ++i)
//     {
//         if(vp[i].second.empty())
//             continue;
//         sort(vp[i].second.begin(), vp[i].second.end());
//         count += vp[i].second.size() * vp[i].first;
//     }
//
//    vector<string> ret;
//    for(i = words.size(); k > 0; --i)
//    {
//        if(vp[i].second.empty())
//            continue;
//        else
//        {
//            for(const auto & j : vp[i].second)
//            {
//                ret.push_back(j);
//                --k;
//            }
//        }
//    }
//    return ret;
//}
//#include <iostream>
//#include <unistd.h>
//using namespace std;
//struct TreeNode
//{
//    int val;
//    TreeNode *left;
//    TreeNode *right;
//    TreeNode() : val(0), left(nullptr), right(nullptr) {}
//    TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
//    TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
//};
//class Solution
//{
//public:
//    int Computing(TreeNode* root, int& ret)
//    {
//        if(root)
//            return 0;
//
//        int left_sum = Computing(root->left, ret) + root->val;
//        int right_sum = Computing(root->right, ret) + root->val;
//        ret += abs(left_sum - right_sum);
//        return left_sum + right_sum - root->val;
//    }
//    int findTilt(TreeNode* root)
//    {
//        int ret = 0;
//        int c = Computing(root, ret);
//        return ret;
//    }
//};
//    FILE* f = fopen("hhhh", "r");
//    if(f == nullptr)
//        cout << strerror(errno) << errno << endl;
//#include <stdio.h>
//#include <unistd.h>
//#include <stdlib.h>
//#include "fun.h"
//int main()
//{
//    AVLTree<int> tree;
//    int v[] = {4, 2, 6, 1, 3, 5, 15, 7, 16, 14};
//    for(auto e : v)
//    {
//        tree.insert(e);
//    }
//    tree.InOrder();
//    cout << tree.AssertAVLTree() << endl;
//    return 0;
//}
//class Person
//{
//public:
//    Person(const char* const & name)
//         : _name(name)
//    {}
//    void Print()
//    {
//        cout << _name << endl;
//    }
//protected:
//    const char* _name;
//};
//class Student:public Person
//{
//public:
//    Student(const int& sid, const char* const & name)
//        : _sid(sid)
//        , Person(name)
//    {}
//private:
//    int _sid;
//};
//class Person
//{
//protected :
//    string _name; // 姓名
//    string _sex; // 性别
//    int _age; // 年龄
//};
//class Student : public Person
//{
//public :
//    int _No ; // 学号
//};
//void Test ()
//{
//    Student sobj ;
//// 1.子类对象可以赋值给父类对象/指针/引用
//    Person pobj = sobj ;
//    Person* pp = &sobj;
//    Person& rp = sobj;
////2.基类对象不能赋值给派生类对象
//    sobj = pobj;
//// 3.基类的指针可以通过强制类型转换赋值给派生类的指针
//    pp = &sobj;
//    Student* ps1 = (Student*)pp; // 这种情况转换时可以的。
//    ps1->_No = 10;
//    pp = &pobj;
//    Student* ps2 = (Student*)pp; // 这种情况转换时虽然可以，但是会存在越界访问的问
//    ps2->_No = 10;
//}
//class Solution
//{
//public:
//    int searchInsert(vector<int>& nums, int target)
//    {
//        if(target > nums[nums.size() - 1])
//            return nums.size();
//
//        int left = 0;
//        int right = nums.size() - 1;
//        while(left < right)
//        {
//            int mid = left + (right - left) / 2;
//            if(nums[mid] >= target)
//            {
//                right = mid;
//            }
//            else
//            {
//                left = mid + 1;
//            }
//        }
//        return left;
//    }
//};
//class A
//{
//public:
//    int Print()
//    {
//        cout << "A" << endl;
//        return 0;
//    }
//    double _a;
//
//};
//class B:public A
//{
//public:
//    void Print() //成员函数，只需要函数名相同就构成隐藏
//    {
//        cout << "B" << endl;
//    }
//public:
//    int _a;
//};
//void Test()
//{
//    B b;
//    //访问同名成员，只会访问到派生类的
//    b.Print();
//    b._a = 3;
//    //显示访问
//    cout << b.B::_a << endl;
//    cout << b.A::_a << endl;
//}
//class Solution
//{
//public:
//    int peakIndexInMountainArray(vector<int>& arr)
//    {
//        int left = 0;
//        int right = arr.size() - 1;
//
//        while(left <= right)
//        {
//            int mid = left + (right - left) / 2;
//
//            if(mid == 0)
//                ++mid;
//            if(mid == arr.size() - 1)
//                --mid;
//
//            if(arr[mid] > arr[mid - 1] && arr[mid] < arr[mid + 1])
//            {
//                left = mid + 1;
//            }
//            else if(arr[mid] < arr[mid - 1] && arr[mid] > arr[mid + 1])
//            {
//                right = mid - 1;
//            }
//            else
//            {
//                return mid;
//            }
//        }
//        return -1;
//    }
//};
//class B;
//class A
//{
//public:
//    friend void Print(const A& a, const B& b);
//private:
//    int _a;
//};
//
//class B:public A
//{
//public:
//private:
//    int _b;
//};
//void Print(const A& a, const B& b)
//{
//    cout << a._a << endl;
//    cout << b._b << endl;
//}
//class A
//{
//public:
//    static void Print()
//    {
//        cout << "_a = " << _a << endl;
//    }
//protected:
//    static int _a;
//};
//int A::_a = 2;  //静态成员变量要在类外面初始化，并表明作用域
//
//class B:public A
//{
//public:
//    static void Add()  //静态成员函数，只能使用静态成员
//    {                  //因为静态成员函数属于整个类，不属于哪个实例化对象
//        ++_a;          //所以静态成员函数里没有this指针，就无法使用非静态成员
//    }
//private:
//    int _b;
//};
//int main()
//{
//    A a;
//    B b;
//    b.Print();
//    b.Add();
//    a.Print();
//    return 0;
//}
//class A
//{
//public:
//    void APrint()
//    {
//        cout << "_a = " << _a << endl;
//    }
//protected:
//    int _a = 1;
//};
//class B:public A
//{
//public:
//    void BPrint()
//    {
//        cout << "_a = " << _a << endl;
//        cout << "_b = " << _b << endl;
//    }
//protected:
//    int _b = 2;
//};
//class C:public B
//{
//public:
//    void CPrint()
//    {
//        cout << "_a = " << _a << endl;
//        cout << "_b = " << _b << endl;
//        cout << "_c = " << _c << endl;
//    }
//private:
//    int _c = 3;
//};
//class P
//{
//public:
//protected:
//    int _p = 0;
//};
//class A:public P
//{
//public:
//protected:
//    int _a = 1;
//};
//class B:public P
//{
//public:
//protected:
//    int _b = 2;
//};
//class C:public A , public B
//{
//public:
//    void Add_P()
//    {
//        _p = _p + 6;
//    }
//private:
//    int _c = 3;
//};
//int main()
//{
//    C c;
//
//    return 0;
//}
//#include <iostream>
//#include <string>
//using namespace std;
//class Person
//{
//public:
//    //构造函数
//    Person()
//    {
//        cout << "Person()" << endl;
//    }
//
//    Person(const string& name, const int& age)
//        : _name(name)
//        , _age(age)
//    {
//        cout << "Person(const string& name, const int& age)" << endl;
//    }
//
//    //拷贝构造
//    Person(const Person& p)
//        : _name(p._name)
//        , _age(p._age)
//    {
//        cout << "Person(const Person& p)" << endl;
//    }
//
//    //赋值运算符重载
//    Person& operator=(const Person& p)
//    {
//        cout << "Person& operator=(const Person* p)" << endl;
//        if(this != &p)
//        {
//            _name = p._name;
//            _age = p._age;
//        }
//        return *this;
//    }
//
//    //析构函数
//    ~Person()
//    {
//        cout << "~Person()" << endl;
//    }
//protected:
//    string _name;
//    int _age;
//};
//class Student:public Person
//{
//public:
//
//    Student()
//    {
//        cout << "Student()" << endl;
//    }
//
//    Student(const string& name, const int& age, const int& id)
//        : Person(name, age)
//        , _id(id)
//    {
//        cout << "Student(const string& name, const int& age, const int& id)" << endl;
//    }
//
//    Student(const Student& s)
//        : Person(s)
//        , _id(s._id)
//    {
//        cout << "Student(const Student& s)" << endl;
//    }
//
//    Student& operator=(const Student& s)
//    {
//        if(this != &s)
//        {
//            Person::operator=((Person&)s);
//            cout << "Student& operator=(const Student* s)" << endl;
//            _id = s._id;
//        }
//        return *this;
//    }
//
//    ~Student()
//    {
//        cout << "~Student()" << endl;
//    }
//
//    void Print()
//    {
//        cout << _name << endl;
//        cout << _age << endl;
//        cout << _id << endl;
//    }
//private:
//    int _id;
//};
//void Test()
//{
//    Student s1("wyd", 20, 25);
////    Student s2;
//    Student s3(s1);
////    s2 = s1;
////    s2.Print();
//    s3.Print();
//
//}
//int main()
//{
//    Test();
////    return 0;
////}
//#include <iostream>
//#include <string>
//using namespace std;
//class P
//{
//public:
//protected:
//    int _p = 0;
//};
//class A:virtual public P
//{
//public:
//protected:
//    int _a = 1;
//};
//class B:virtual public P
//{
//public:
//protected:
//    int _b = 2;
//};
//class C:public A , public B
//{
//public:
//    void Add_P()
//    {
//        _p = _p + 6;    //不知道访问的哪个_p
//    }
//private:
//    int _c = 3;
//};
//class Person
//{
//public:
//    //构造函数
//    Person(const string& name, const int& age)
//            : _name(name)
//            , _age(age)
//    {
//        cout << "Person(const string& name, const int& age)" << endl;
//    }
//
//    //拷贝构造
//    Person(const Person& p = Person("wyd", 2))
//            : _name(p._name)
//            , _age(p._age)
//    {
//        cout << "Person(const Person& p)" << endl;
//    }
//
//    //赋值运算符重载
//    Person& operator=(const Person& p)
//    {
//        cout << "Person& operator=(const Person* p)" << endl;
//        if(this != &p)
//        {
//            _name = p._name;
//            _age = p._age;
//        }
//        return *this;
//    }
//
//    //析构函数
//    ~Person()
//    {
//        cout << "~Person()" << endl;
//    }
//protected:
//    string _name;
//    int _age;
//};
//class Student:public Person
//{
//public:
//
//    Student()
//    {
//        cout << "Student()" << endl;
//    }
//
//    Student(const string& name, const int& age, const int& id)
//            : Person(name, age)
//            , _id(id)
//    {
//        cout << "Student(const string& name, const int& age, const int& id)" << endl;
//    }
//
//    Student(const Student& s)
//            : _id(s._id)
//    {
//        cout << "Student(const Student& s)" << endl;
//    }
//
//    Student& operator=(const Student& s)
//    {
//        if(this != &s)
//        {
//            Person::operator=((Person&)s);
//            cout << "Student& operator=(const Student* s)" << endl;
//            _id = s._id;
//        }
//        return *this;
//    }
//
//    ~Student()
//    {
//        cout << "~Student()" << endl;
//    }
//
//    void Print()
//    {
//        cout << _name << endl;
//        cout << _age << endl;
//        cout << _id << endl;
//    }
//private:
//    int _id;
//};
//void Test()
//{
//    Student s1("hhh", 20, 25);
////    Student s2;
//    Student s3(s1);
////    s2 = s1;
////    s2.Print();
//    s3.Print();
//
//}
//int main()
//{
//    Test();
//    return 0;
//
class Solution 
{
public:
    int findMin(vector<int>& nums) 
    {

        int min = nums[0];
        int left = 0;
        int right = nums.size() - 1;

        while(left < right)
        {
            int mid = left + (right - left) / 2;
            //这里有特殊情况，当有2个元素的时候，需要比较后面的元素，因为两个元素为降序
            if(mid == 0)
            {
                min = min > nums[1] ? nums[1] : min;
                return min;
            }
            //因为是旋转，所以数组只有两个升序（两个元素除外），比较规则分为三类，并且数组中仅存在两个小值，一个在下表为0，一个在另外下标处
            //4，5，6，0，1   ｜｜ 1，2，3，4，5
            //当mid前后处于升序，分2种情况
            if(nums[mid] > nums[mid - 1] && nums[mid] < nums[mid + 1]) 
            {
                //1. 非完全升序，比较mid和right，当right值小，说明mid到right之间有小值，区间换到mid——right
                if(nums[right] < nums[mid])
                    left = mid + 1;
                //2. 完全升序，则left——mid之间有小值
                else
                    right = mid - 1;
            }
            //当mid就是小值，与min比较，返回小的
            else if(nums[mid] < nums[mid - 1] && nums[mid] < nums[mid + 1])
            {
                min = min > nums[mid] ? nums[mid] : min;
                break;
            }
            //当mid为最大，则后面的为小值，与min比较，返回小的
            else if(nums[mid] > nums[mid - 1] && nums[mid] > nums[mid + 1])
            {
                min = min > nums[mid + 1] ? nums[mid + 1] : min;
                break;
            }
            else;
        }
        return min;
    }
};
class Solution 
{
public:
    int findPeakElement(vector<int>& arr) 
    {
        if(arr.size() == 1)
            return 0;

        int left = 0;
        int right = arr.size() - 1;

        while(left <= right)
        {
            int mid = left + (right - left) / 2;
            if(mid == 0 || mid == arr.size() - 1)
            {
                if(mid == 0)
                {
                    if(arr[mid] > arr[mid + 1])
                        return mid;
                    else
                        left = mid + 1;
                }
                else
                {
                    if(arr[mid] > arr[mid - 1])
                        return mid;
                    else 
                        right = mid - 1;
                }
            }
            else if(arr[mid] > arr[mid - 1] && arr[mid] < arr[mid + 1])
            {                                  
                left = mid + 1;
            }
            else if(arr[mid] < arr[mid - 1] && arr[mid] > arr[mid + 1])
            {
                right = mid - 1;
            }
            else if(arr[mid] < arr[mid - 1] && arr[mid] < arr[mid + 1])
            {
                if(arr[mid - 1] > arr[mid + 1])
                {
                    right = mid - 1;
                }
                else
                {
                    left = mid + 1;
                }
            }
            else
            {
                return mid;
            }
        }
        return -1;
    }
};
 *///#include <iostream>
//using namespace std;
//class Person
//{
//public :
//    Person(const char* name = "peter")
//            : _name(name )
//    {
//        cout<<"Person()" <<endl;
//    }
//    Person(const Person& p)
//            : _name(p._name)
//    {
//        cout<<"Person(const Person& p)" <<endl;
//    }
//    Person& operator=(const Person& p )
//    {
//        cout<<"Person operator=(const Person& p)"<< endl;
//        if (this != &p)
//            _name = p ._name;
//        return *this ;
//    }
//    ~Person()
//    {
//        cout<<"~Person()" <<endl;
//    }
//protected :
//    string _name ; // 姓名
//};
//class Student : public Person
//{
//public :
//    Student(const char* name, int num)
//            : Person(name )
//            , _num(num )
//    {
//        cout<<"Student()" <<endl;
//    }
//    Student(const Student& s)
//            : Person(s)
//            , _num(s ._num)
//    {
//        cout<<"Student(const Student& s)" <<endl ;
//    }
//    Student& operator = (const Student& s )
//    {
//        cout<<"Student& operator= (const Student& s)"<< endl;
//        if (this != &s)
//        {
//            Person::operator =(s);
//            _num = s ._num;
//        }
//        return *this ;
//    }
//    ~Student()
//    {
//        cout<<"~Student()" <<endl;
//    }
//protected :
//    int _num ; //学号
//};
//void Test ()
//{
//    Student s1 ("jack", 18);
//    Student s2 (s1);
//    Student s3 ("rose", 17);
//    s1 = s3 ;
//}
//int main()
//{
//    Test();
//    return 0;
//}
//#include "RBTree.h"
//void vest()
//{
//    const int N = 10000;
//    vector<int> arr;
//    arr.reserve(N);
//    srand(time(0));
//
//    for (size_t i = 0; i < N; i++)
//    {
//        arr.push_back(rand() + i);
//    }
//
//    size_t begin2 = clock();
//    RBTree<int> rb;
//    for(auto e : arr)
//    {
//        rb.insert(e);
//    }
//    rb.InOrder();
//    if(rb.Check())
//        cout << "true" << endl;
//    else
//        cout << "false" << endl;
//}
//int main()
//{
//    vest();
//    return 0;
//    RBTree<int> rb;
//    int arr[] = {13,8,17,1,
//                 11,15,25,6,22,27,99,88,77,66,55,44,33};
//    for(auto e : arr)
//    {
//        rb.insert(e);
//    }
//    rb.InOrder();
//    if(rb.Check())
//        cout << "true" << endl;
//    else
//        cout << "false" << endl;
//}
//#include <iostream>
//using namespace std;
//int main()
//{
//    string::iterator it = s.begin();
//    while(it != s.end())
//    {
//
//    }
//    return 0;
//}

//list<pair<int, int>> l;
//l.push_back(make_pair(1,2));
//l.push_back(make_pair(2,2));
//l.push_back(make_pair(3,2));
//l.push_back(make_pair(4,2));
//l.push_back(make_pair(5,2));
//auto it = l.begin();
//it->first;
//#include "newmap.h"
//#include "newset.h"
//void test_map()
//{
//    wyd::map<int, char> mm;
//    for(int i = 0; i < 10; ++i)
//    {
//        mm.insert(make_pair(i, i + 'a'));
//    }
//    wyd::map<int, char>::iterator it = mm.begin();
//    while(it != mm.end())
//    {
//        cout << it->second << " ";
//        ++it;
//    }
//    cout << endl;
//}
//void test_set()
//{
//    wyd::set<int> s;
//    int arr[] = {1,5,4,3,2,7,8,9,77};
//    for(int i : arr)
//    {
//        s.insert(i);
//    }
//    wyd::set<int>::iterator it = s.begin();
//    while(it != s.end())
//    {
//        cout << *it << " ";
//        ++it;
////        cout << *it++ << endl;
//    }
//    cout << endl;
//    wyd::set<int>::iterator it = s.end();
//    while(it != s.begin())
//    {
//        cout << *it << " ";
//        cout << *it-- << endl;
//    }
//    cout << endl;
//}
//#include <iostream>
//#include <map>
//using namespace std;
//vector<int> intersect(vector<int>& nums1, vector<int>& nums2)
//{
//    map<int, int> n1;
//    map<int, int> n2;
//    vector<int> ret;
//
//    for (auto e: nums1) {
//        ++n1[e];
//    }
//    for (auto e: nums2) {
//        ++n2[e];
//    }
//
//    auto cur1 = n1.begin();
//    auto cur2 = n2.begin();
//    while (cur1 != n1.end() && cur2 != n2.end())
//    {
//        if (cur1->first > cur2->first)
//        {
//            ++cur2;
//        }
//        else if (cur1->first < cur2->first)
//        {
//            ++cur1;
//        }
//        else
//        {
//            int same_size = cur1->second > cur2->second ? cur2->second : cur1->second;
//            while (same_size--)
//            {
//                ret.push_back(cur1->first);
//            }
//            ++cur1;
//            ++cur2;
//        }
//    }
//
//    return ret;
//}
//int main()
//{
//    vector<int> n1 = {1, 2, 2, 1};
//    vector<int> n2 = {2, 2};
//    vector<int> ret = intersect(n1, n2);
//    for(auto e : ret)
//    {
//        cout << e << " ";
//    }
//    cout << endl;
//    return 0;
//}
//    test_map();
//    test_set();
//#include "NewAVLTree.h"

//int main()
//{
//    AVL<int> avl;
//    return 0;
//}
////设计一个算法，采用分治法求一个整数序列中的最大和最小元素。
////这里采用快排的方法来实现分治法
//// 并且使用基准数为区间的随机值和三路划分的思路来优化我们的快排，使时间复杂度接近O(nlogn)
//#include <iostream>
//#include <vector>
//using namespace std;
//void QuickSort(vector<int>& nums, int left, int right)
//{
//    //大致思路：将数组分为三个区域，只需要排序非重复的数的区间即可
//    //[0, left] < key
//    //[left + 1, cur - 1]  == key
//    //[cur, right - 1]  未扫描
//    //[right, n - 1] > key
//
//    //返回条件
//    if(left + 1 >= right - 1)
//        return;
//
//    //记录最开始的左右区间，为递归传参作准备
//    int flag_left = left;
//    int flag_right = right;
//
//    int r = rand();
//    //记录基准值
//    int key = nums[r % ((right - 1) - (left + 1) + 1) + (left + 1)];
//    int cur = left + 1;
//
//
//    while(cur < right)
//    {
//        if(nums[cur] > key)
//            swap(nums[--right], nums[cur]);
//        else if(nums[cur] < key)
//            swap(nums[++left], nums[cur++]);
//        else
//            ++cur;
//    }
//
//    QuickSort(nums, flag_left, left + 1);
//    QuickSort(nums, right - 1, flag_right);
//}
//vector<int> sortArray(vector<int>& nums)
//{
//    //种下随机数的种子
//    srand(time(nullptr));
//
//    int left = -1, right = nums.size();
//    //快速排序
//    QuickSort(nums, left, right);
//    return nums;
//}
//
//int main()
//{
//    vector<int> arr = {-4,0,7,4,9,-5,-1,0,-7,-1};
//    sortArray(arr);
//
//    cout << "max = " << arr[arr.size() - 1] << endl;
//    cout << "min = " << arr[0] << endl;
//    return 0;
//}

////假设二叉树采用二叉链存储结构进行存储，设计一个算法采用分治法求一棵二叉树bt 的高度

//// 三数取中
//int GetMidi(int* a, int left, int right)
//{
//    int mid = (left + right) / 2;
//    // left mid right
//    if (a[left] < a[mid])
//    {
//        if (a[mid] < a[right])
//        {
//            return mid;
//        }
//        else if (a[left] > a[right])  // mid是最大值
//        {
//            return left;
//        }
//        else
//        {
//            return right;
//        }
//    }
//    else // a[left] > a[mid]
//    {
//        if (a[mid] > a[right])
//        {
//            return mid;
//        }
//        else if (a[left] < a[right]) // mid是最小
//        {
//            return left;
//        }
//        else
//        {
//            return right;
//        }
//    }
//}
//#include <stdio.h>
//void Swap(int* x, int* y)
//{
//    int tmp = *x;
//    *x = *y;
//    *y = tmp;
//}
//int PartSort(int* a, int left, int right)
//{
//    int midi = (left + right) / 2;
//    Swap(&a[left], &a[midi]);
//
//    int prev = left;
//    int cur = prev + 1;
//
//    int keyi = left;
//    while (cur <= right)
//    {
//        if (a[cur] < a[keyi] && ++prev != cur)
//        {
//            Swap(&a[prev], &a[cur]);
//        }
//
//        ++cur;
//    }
//
//    Swap(&a[prev], &a[keyi]);
//    return prev;
//}
//void QuickSort(int* a, int begin, int end)
//{
//    if (begin >= end)
//        return;
//
//
//    int keyi = PartSort(a, begin, end);
//
//    // [begin, keyi-1] keyi [keyi+1, end]
//    QuickSort(a, begin, keyi - 1);
//    QuickSort(a, keyi + 1, end);
//}
//void GetMaxAndMin(int* a, int len)
//{
//    QuickSort(a, 0, len - 1);
//    printf("max = %d min = %d\n", a[0], a[len - 1]);
//}
//int main()
//{
//    int arr[] = {1,3,90,7,6,5,4,3,2,-3};
//    GetMaxAndMin(arr, sizeof(arr)/sizeof(int));
//    return 0;
//}
//////template <class T>
//////struct TreeNode
//////{
//////    typedef TreeNode<T> Node;
//////    Node* _left;
//////    Node* _right;
//////    T _data;
//////};
//////template <class T>
////int TreeHeight(TreeNode* root)
////{
////    if(root == NULL)
////        return 0;
////
////    int leftH = TreeHeight(root->_left);
////    int rightH = TreeHeight(root->_right);
////
////    return leftH > rightH ? leftH + 1 : rightH + 1;
////}
////
////int main()
////{
////    set<int> s;
////    int arr[] = {9,7,4,3,1,2,5,88};
////    for(auto e : arr)
////    {
////        s.insert(e);
////    }
////    cout << "树的高度为" <<  TreeHeight(s) << endl;
////    return 0;
////}
//#include <iostream>
//using namespace std;
//int main()
//{
//    return 0;
//}
//#include <iostream>
//#include <set>
//#include <unordered_set>
//#include <unordered_map>
//using namespace  std;
//void Test_umap()
//{
//    unordered_map<int, char> umap;
//    int arr[] = {1,4,5,2,6,7};
//    for(auto e : arr)
//    {
//        umap.insert(make_pair(e,e + 'a'));
//    }
//    for(auto e : umap)
//    {
//        cout << e.first << ":" << e.second << endl;
//    }
//};
//void Test_uset()
//{
//    unordered_set<int> uset;
//    int arr[] = {1,4,5,2,6,7};
//    for(auto e : arr)
//    {
//        uset.insert(e);
//    }
//    for(auto e : uset)
//    {
//        cout << e << " ";
//    }
//    cout << endl;
//}
//void test_set1()
//{
//    set<int> s;
//    s.insert(3);
//    s.insert(1);
//    s.insert(5);
//    s.insert(7);
//
//    for (auto e : s)
//    {
//        cout << e << " ";
//    }
//    cout << endl;
//
//    unordered_set<int> us;
//    us.insert(3);
//    us.insert(1);
//    us.insert(5);
//    us.insert(7);
//
//    for (auto e : us)
//    {
//        cout << e << " ";
//    }
//    cout << endl;
//}
//
//struct HashPerson
//{
//    size_t operator()(Person& p)
//    {
//        return p._id;
//    }
//};
//
//int main()
//{
////    Test_umap();
////    Test_uset();
//    test_set1();
//    return 0;
//}
//#include "HashTable.h"
//void Test1()
//{
//    HashTable<int, Getint<int>> ht;
//    int arr[] = {1,11,2 ,3,5,6,77,12,88,66,13,14,15};
//    for(auto& e : arr)
//    {
//        ht.insert(e);
//    }
//    ht.erase(11);
////    if(ht.find(11) == nullptr)
////        cout << "false" << endl;
////    else
////        cout << "yes" << endl;
//}
//void Test2()
//{
//    HashTable<string, Getint<string>> sh;
//    vector<string> vs = {"hhh", "666"};
//    for(auto& e : vs)
//    {
//        sh.insert(e);
//    }
//    int a = 0;
//}
//int main()
//{
//    Test2();
//    return 0;
//}
//写一个堆排序
//#include <iostream>
//using namespace std;
//#include "HashTable.h"
//void Test1()
//{
//    HashList<int> hash;
//    int arr[] = {1,11,2,22,3,33,4,44,54,6,7,123};
//    for(auto e : arr)
//    {
//        hash.insert(e);
//    }
////    if(hash.find(29))
////        cout << "Y" << endl;
////    else
////        cout << "N" << endl;
//    for(auto e : arr)
//    {
//        hash.erase(e);
//    }
//}
//#include "my_unorder_Map.h"
//#include "my_unorder_Set.h"
//void Test1()
//{
//    wyd::unordered_set<int> s;
//    int arr[] = {1,11,2,22,3,33,4,44,5,55,6,66,123,21};
//    for(auto e : arr)
//    {
//        s.insert(e);
//    }
//    for(auto e : s)
//    {
//        cout << e << " ";
//    }
//    cout << endl;
//}
//void Test2()
//{
//    wyd::unordered_set<string> set_string;
//    vector<string> vs = {"hhh", "hello", "world", "1", "12",
//                         "123", "qqqq", "asdf", "qwe", "gfd",
//                         "666", "777"};
//    for(auto& e : vs)
//    {
//        set_string.insert(e);
//    }
//    auto it = set_string.begin();
//    while(it != set_string.end())
//    {
//        cout << *it << " ";
//        ++it;
//    }
//    cout << endl;
//    for(auto& e : set_string)
//    {
//        cout << e << " ";
//    }
//    cout << endl;
//}
//void Test3()
//{
//    wyd::unordered_map<string, string> umap;
//    umap.insert(make_pair("sort", "排序"));
//    umap.insert(make_pair("so", "排"));
//    umap.insert(make_pair("rt", "序"));
//    umap.insert(make_pair("11sort", "11排序"));
//    umap.insert(make_pair("22sort", "22排序"));
//    for(auto e : umap)
//    {
//        cout << e.first << ":" << e.second << endl;
//    }
//}
//int main()
//{
//
//    Test3();
//    return 0;
//}














//#include <iostream>
////#include <string>
////#include <vector>
////#include <list>
////#include <queue>
////#include <deque>
////#include <stack>
////#include <map>
////#include <set>
//#include <cassert>
//using namespace std;
////创建一棵树，必须要先创建树的节点
////创建AVL树的节点
////节点应该包括 指向左右子树的指针；节点存储的值；节点的平衡因子；节点指向父亲节点的指针
////而我们在找到树的节点时，应该可以随意去访问树的左右指针，父指针和内部的元素，所以这里需定义节点为public，struct类默认权限为public
//template <class T>
//struct AVLTreeNode
//{
//    AVLTreeNode(const T& val)
//        : _left(nullptr)
//        , _right(nullptr)
//        , _parent(nullptr)
//        , _bf(0)
//        , _val(val)
//    {}
//    typedef AVLTreeNode<T> Node;
//    Node* _left;
//    Node* _right;
//    Node* _parent;
//    int _bf; /// balance factor
//    T _val;
//};
//
////定义好树的节点，就可以开始定义树，树这里我们就不希望访问树的成员变量，而希望使用成员函数，所以我们设定为class类
//template <class T>
//class AVLTree
//{
//public:
//    typedef AVLTreeNode<T> Node;
//    AVLTree()
//        : _root(nullptr)
//    {}
//
//    //计算高度
//    int Height()
//    {
//        return _Height(_root);
//    }
//
//    //AVL树的验证
//    //要验证一个AVL树，我们就不应该根据bf来判定，因为这是一个毫无疑义的验证方法
//    //当你的bf值记录更新错误，我们还是按照错误的方式来验证的，验证就永远为AVL树
//    //所以我们要根据其左右子树的高度去计算
//    bool AssertAVLTree()
//    {
//        int height = 0;
//        return _AssertAVLTree(_root, height);
//    }
//
//    //中序遍历
//    void InOrder()
//    {
//        _InOrder(_root);
//        cout << endl;
//    }
//
//    //AVL树的插入，要满足二叉搜索树的性质，左孩子小于根，右孩子大于根
//    bool insert(const T& val)
//    {
//        if(_root == nullptr) //空树
//        {
//            _root = new Node(val);
//            if(_root == nullptr)
//                assert(false);
//        }
//        else //不为空树
//        {
//            Node* cur = _root;
//            Node* parent = _root;
//
//            //根据二叉搜索树性质判断插入的位置
//            while(cur)
//            {
//                if(cur->_val < val)
//                {
//                    parent = cur;
//                    cur = cur->_right;
//                }
//                else if(cur->_val > val)
//                {
//                    parent = cur;
//                    cur = cur->_left;
//                }
//                else
//                {
//                    return false;
//                }
//            }
//
//            //插入新节点
//            Node* newnode = new Node(val);
//            if(parent->_val > val)
//            {
//                parent->_left = newnode;
//            }
//            else
//            {
//                parent->_right = newnode;
//            }
//            newnode->_parent = parent;
//
//            //更新平衡因子
//            while(parent)
//            {
//                if(parent->_left == newnode)
//                {
//                    --parent->_bf;
//                }
//                else
//                {
//                    ++parent->_bf;
//                }
//
//                if (parent->_bf == 0)
//                {
//                    break;
//                }
//                else if (parent->_bf == 1 || parent->_bf == -1)
//                {
//                    newnode = parent;
//                    parent = parent->_parent;
//                }
//                else if (parent->_bf == 2 || parent->_bf == -2)
//                {
//                    //旋转
//                    if(parent->_bf == -2 && newnode->_bf == -1)
//                    {
//                        //右单旋
//                        RotationR(parent);
//                    }
//                    else if(parent->_bf == -2 && newnode->_bf == 1)
//                    {
//                       //先左后右
//                        RotationLR(parent);
//                    }
//                    else if(parent->_bf == 2 && newnode->_bf == 1)
//                    {
//                        //左单旋
//                        RotationL(parent);
//                    }
//                    else if(parent->_bf == 2 && newnode->_bf == -1)
//                    {
//                        RotationRL(parent);
//                    }
//                    else;
//
//                    break;
//                }
//                else;
//            }
//
//        }
//        return true;
//    }
//private:
//    Node* _root;
//    void _InOrder(Node* root)
//    {
//        if(root == nullptr)
//            return;
//        _InOrder(root->_left);
//        cout << root->_val << " ";
//        _InOrder(root->_right);
//    }
//    void RotationRL(Node* parent)
//    {
//        Node* pR = parent->_right;
//        Node* pRL = pR->_left;
//        int bf = pRL->_bf;
//
//        //先右单旋
//        RotationR(pR);
//        //后左单旋
//        RotationL(parent);
//
//        if(bf == 1)
//        {
//            pR->_bf = 0;
//            parent->_bf = -1;
//            pRL->_bf = 0;
//        }
//        else if(bf == -1)
//        {
//            pR->_bf = 1;
//            parent->_bf = 0;
//            pRL->_bf = 0;
//        }
//        else
//        {
//            pR->_bf = 0;
//            parent->_bf = 0;
//            pRL->_bf = 0;
//        }
//
//    }
//    void RotationLR(Node* parent)
//    {
//        Node* pL = parent->_left;
//        Node* pLR = pL->_right;
//        int bf = pLR->_bf;
//
//        //先左单旋
//        RotationL(pL);
//        //后右单旋
//        RotationR(parent);
//
//        if(bf == 1)
//        {
//            pL->_bf = -1;
//            parent->_bf = 0;
//            pLR->_bf = 0;
//        }
//        else if(bf == -1)
//        {
//            pL->_bf = 0;
//            parent->_bf = 1;
//            pLR->_bf = 0;
//        }
//        else
//        {
//            pL->_bf = 0;
//            parent->_bf = 0;
//            pLR->_bf = 0;
//        }
//    }
//    void RotationL(Node* parent)
//    {
//        Node* pR = parent->_right;
//        Node* pRL = pR->_left;
//
//        parent->_right = pRL;
//        if(pRL)
//            pRL->_parent = parent;
//        pR->_left = parent;
//        Node* ppnode = parent->_parent;
//        parent->_parent = pR;
//
//        if(parent == _root)
//        {
//            _root = pR;
//            pR->_parent = nullptr;
//        }
//        else
//        {
//            if(ppnode->_left == parent)
//                ppnode->_left = pR;
//            else
//                ppnode->_right = pR;
//            pR->_parent = ppnode;
//        }
//
//        parent->_bf = 0;
//        pR->_bf = 0;
//    }
//    void RotationR(Node* parent)
//    {
//        Node* pL = parent->_left;
//        Node* pLR = pL->_right;
//
//        parent->_left = pLR;
//        if(pLR)
//            pLR->_parent = parent;
//        pL->_right = parent;
//        Node* ppnode = parent->_parent;
//        parent->_parent = pL;
//
//        if(_root == parent)
//        {
//            _root = pL;
//            pL->_parent = nullptr;
//        }
//        else
//        {
//            if(ppnode->_left == parent)
//                ppnode->_left = pL;
//            else
//                ppnode->_right = pL;
//            pL->_parent = ppnode;
//        }
//
//        pL->_bf = 0;
//        parent->_bf = 0;
//    }
//
//
//
//    bool _AssertAVLTree(Node* root, int& height)
//    {
//
//        if(root == nullptr)
//        {
//            height = 0;
//            return true;
//        }
//
//        //计算左子树高度
//        int leftH = 0;
//        //计算右子树高度
//        int rightH = 0;
//        if(!_AssertAVLTree(root->_left, leftH)
//        || !_AssertAVLTree(root->_right, rightH))
//            return false;
//
//
//        if(abs(leftH - rightH) >= 2)
//        {
//            cout << "树高度差超过2" << endl;
//            return false;
//        }
//        else if(rightH - leftH != root->_bf)
//        {
//            cout << "平衡因子数据异常" << endl;
//            return false;
//        }
//
//        height = leftH > rightH ? leftH + 1 : rightH + 1;
//        return true;
//    }
//    int _Height(Node* root)
//    {
//        if(root == nullptr)
//            return 0;
//
//        int left_height = _Height(root->_left);
//        int right_height = _Height(root->_right);
//
//        return left_height > right_height ? left_height + 1 : right_height + 1;
//    }
//};
#pragma once
#include <iostream>
#include<assert.h>
#include<vector>

template<class K, class V>
struct AVLTreeNode
{
    AVLTreeNode<K, V>* _left;
    AVLTreeNode<K, V>* _right;
    AVLTreeNode<K, V>* _parent;
    int _bf; // balance factor
    pair<K, V> _kv;

    AVLTreeNode(const pair<K, V>& kv)
            :_left(nullptr)
            , _right(nullptr)
            , _parent(nullptr)
            , _bf(0)
            , _kv(kv)
    {}
};

template<class K, class V>
class AVLTree
{
    typedef AVLTreeNode<K, V> Node;
public:
    bool Insert(const pair<K, V>& kv)
    {
        if (_root == nullptr)
        {
            _root = new Node(kv);
            return true;
        }

        Node* parent = nullptr;
        Node* cur = _root;
        while (cur)
        {
            if (cur->_kv.first < kv.first)
            {
                parent = cur;
                cur = cur->_right;
            }
            else if (cur->_kv.first > kv.first)
            {
                parent = cur;
                cur = cur->_left;
            }
            else
            {
                return false;
            }
        }

        cur = new Node(kv);
        if (parent->_kv.first < kv.first)
        {
            parent->_right = cur;
        }
        else
        {
            parent->_left = cur;
        }
        cur->_parent = parent;

        while (parent)
        {
            if(cur == parent->_left)
            {
                parent->_bf--;
            }
            else
            {
                parent->_bf++;
            }

            if (parent->_bf == 0)
            {
                break;
            }
            else if (parent->_bf == 1 || parent->_bf == -1)
            {
                cur = cur->_parent;
                parent = parent->_parent;
            }
            else if (parent->_bf == 2 || parent->_bf == -2)
            {
                // 旋转处理
                if (parent->_bf == 2 && cur->_bf == 1)
                {
                    RotateL(parent);
                }
                else if (parent->_bf == -2 && cur->_bf == -1)
                {
                    RotateR(parent);
                }
                else if (parent->_bf == -2 && cur->_bf == 1)
                {
                    RotateLR(parent);
                }
                else
                {
                    RotateRL(parent);
                }

                break;
            }
            else
            {
                // 插入之前AVL树就有问题
                assert(false);
            }
        }

        return true;
    }

    void RotateL(Node* parent)
    {
        Node* subR = parent->_right;
        Node* subRL = subR->_left;

        parent->_right = subRL;
        if(subRL)
            subRL->_parent = parent;

        subR->_left = parent;
        Node* ppnode = parent->_parent;
        parent->_parent = subR;

        if (parent == _root)
        {
            _root = subR;
            subR->_parent = nullptr;
        }
        else
        {
            if (ppnode->_left == parent)
            {
                ppnode->_left = subR;
            }
            else
            {
                ppnode->_right = subR;
            }
            subR->_parent = ppnode;
        }

        parent->_bf = 0;
        subR->_bf = 0;
    }

    void RotateR(Node* parent)
    {
        Node* subL = parent->_left;
        Node* subLR = subL->_right;

        parent->_left = subLR;
        if (subLR)
            subLR->_parent = parent;

        subL->_right = parent;

        Node* ppnode = parent->_parent;
        parent->_parent = subL;

        if (parent == _root)
        {
            _root = subL;
            subL->_parent = nullptr;
        }
        else
        {
            if (ppnode->_left == parent)
            {
                ppnode->_left = subL;
            }
            else
            {
                ppnode->_right = subL;
            }
            subL->_parent = ppnode;
        }

        subL->_bf = 0;
        parent->_bf = 0;
    }

    void RotateLR(Node* parent)
    {
        Node* subL = parent->_left;
        Node* subLR = subL->_right;

        int bf = subLR->_bf;
        RotateL(parent->_left);
        RotateR(parent);

        if (bf == -1)
        {
            subLR->_bf = 0;
            subL->_bf = 0;
            parent->_bf = 1;
        }
        else if (bf == 1)
        {
            subLR->_bf = 0;
            subL->_bf = -1;
            parent->_bf = 0;
        }
        else if (bf == 0)
        {
            subLR->_bf = 0;
            subL->_bf = 0;
            parent->_bf = 0;
        }
        else
        {
            assert(false);
        }
    }

    void RotateRL(Node* parent)
    {
        Node* subR = parent->_right;
        Node* subRL = subR->_left;
        int bf = subRL->_bf;

        RotateR(subR);
        RotateL(parent);

        subRL->_bf = 0;
        if (bf == 1)
        {
            subR->_bf = 0;
            parent->_bf = -1;
        }
        else if (bf == -1)
        {
            parent->_bf = 0;
            subR->_bf = 1;
        }
        else
        {
            parent->_bf = 0;
            subR->_bf = 0;
        }
    }

    void _InOrder(Node* root)
    {
        if (root == nullptr)
            return;

        _InOrder(root->_left);
        cout << root->_kv.first << "[" << root->_bf << "]" << endl;
        _InOrder(root->_right);
    }

    void InOrder()
    {
        _InOrder(_root);
    }

    int _Height(Node* root)
    {
        if (root == nullptr)
            return 0;

        int leftHeight = _Height(root->_left);
        int rightHeight = _Height(root->_right);

        return leftHeight > rightHeight ? leftHeight + 1 : rightHeight + 1;
    }

    int Height()
    {
        return _Height(_root);
    }

    bool _IsBalance(Node* root, int& height)
    {
        if (root == nullptr)
        {
            height = 0;
            return true;
        }

        int leftHeight = 0, rightHeight = 0;
        if (!_IsBalance(root->_left, leftHeight)
            || !_IsBalance(root->_right, rightHeight))
        {
            return false;
        }

        if (abs(rightHeight - leftHeight) >= 2)
        {
            cout <<root->_kv.first<<"不平衡" << endl;
            return false;
        }

        if (rightHeight - leftHeight != root->_bf)
        {
            cout << root->_kv.first <<"平衡因子异常" << endl;
            return false;
        }

        height = leftHeight > rightHeight ? leftHeight + 1 : rightHeight + 1;

        return true;
    }

    bool IsBalance()
    {
        int height = 0;
        return _IsBalance(_root, height);
    }

    size_t Size()
    {
        return _Size(_root);
    }

    size_t _Size(Node* root)
    {
        if (root == NULL)
            return 0;

        return _Size(root->_left)
               + _Size(root->_right) + 1;
    }

    Node* Find(const K& key)
    {
        Node* cur = _root;
        while (cur)
        {
            if (cur->_kv.first < key)
            {
                cur = cur->_right;
            }
            else if (cur->_kv.first > key)
            {
                cur = cur->_left;
            }
            else
            {
                return cur;
            }
        }

        return NULL;
    }
private:
    Node* _root = nullptr;
};




























#pragma once
#include <iostream>
#include <vector>
#include <cstring>
using namespace std;

////////////////////////////////////////////////////////////
template <class T>
class Comp
{
public:
    bool operator()(const T& val1, const T& val2)
    {
        return val1 == val2;
    }
};

template<>
class Comp<string>
{
public:
    bool operator()(const string& s1, const string& s2)
    {
        return strcmp(s1.c_str(), s2.c_str()) == 0;
    }
};
////////////////////////////////////////////////////////////
template<class T>
class GetInt
{
public:
    size_t operator()(const T& val)
    {
        return (size_t)val;
    }
};

template<>
class GetInt<string>
{
public:
    size_t operator()(const string& s)
    {
        size_t ret = 0;
        for(auto& e : s)
        {
            ret += e;
            ret *= 131;
        }
        return ret;
    }
};
////////////////////////////////////////////////////////////
template <class T>
struct HashListNode
{
    explicit HashListNode(const T& val)
        : _val(val)
        , _next(nullptr)
    {}

    T _val;
    HashListNode<T>* _next;
};
////////////////////////////////////////////////////////////

template <class K, class T, class TOfK, class GetInt>
struct Hash_Iterator
{
    typedef HashListNode<T> Node;
    typedef Hash_Iterator<K, T, TOfK, GetInt> Self;

    Hash_Iterator(Node* node, vector<Node*>* v)
        : _hash_node(node)
        , _v(v)
    {}

    T& operator*()
    {
        return _hash_node->_val;
    }

    T* operator->()
    {
        return &_hash_node->_val;
    }

    Self& operator++()
    {
        if(_hash_node->_next)
        {
            _hash_node = _hash_node->_next;
        }
        else
        {
            TOfK t_of_k;
            GetInt get_int;
            int hash_pos = get_int(t_of_k(_hash_node->_val)) % _v->size();
            ++hash_pos;

            while(hash_pos < _v->size())
            {
                if((*_v)[hash_pos] != nullptr)
                {
                    _hash_node = (*_v)[hash_pos];
                    break;
                }
                ++hash_pos;
            }
            if(hash_pos == _v->size())
                _hash_node = nullptr;
        }
        return *this;
    }

    bool operator!=(Self another)
    {
        return _hash_node != another._hash_node;
    }

    bool operator==(Self another)
    {
        return _hash_node == another._hash_node;
    }

    Node* _hash_node;
    vector<Node*>* _v;
};

////////////////////////////////////////////////////////////
template <class K, class T, class TOfK, class GetInt, class Comp = Comp<K>>
class HashList
{
public:

    typedef HashListNode<T> Node;
    typedef Hash_Iterator<K, T, TOfK, GetInt> iterator;

    iterator begin()
    {
        for(auto e : _hs)
        {
            if(e != nullptr)
            {
                return iterator(e, &_hs);
            }
        }
        return end();
    }

    iterator end()
    {
        return iterator(nullptr, &_hs);
    }

    HashList()
    {
        _hs.resize(10, nullptr);
    }
    explicit HashList(const size_t size)
    {
        _hs.resize(size, nullptr);
    }
    ~HashList()
    {
        for(auto e : _hs)
        {
            Node* cur = e;
            while(cur)
            {
                e = cur->_next;
                delete cur;
                cur = e;
            }
        }
    }

    bool insert(const T& val)
    {
        TOfK t_of_k;
        GetInt get_i;
        if(find(val))
            return false;

        if(_n == _hs.size())
        {
            HashList<K, T, TOfK, GetInt> new_hs(_hs.size() * 2);
            for(auto& e : _hs)
            {
                Node *cur = e;
                while (cur)
                {
                    size_t new_pos = get_i(t_of_k(cur->_val)) % new_hs._hs.size();
                    e = cur->_next;
                    cur->_next = new_hs._hs[new_pos];
                    new_hs._hs[new_pos] = cur;
                    cur = e;
                }
            }
            _hs.swap(new_hs._hs);

        }

        size_t hash_pos =  get_i(t_of_k(val)) % _hs.size();
        Node* newnode = new Node(val);
        newnode->_next = _hs[hash_pos];
        _hs[hash_pos] = newnode;
        ++_n;
        return true;
    }

    Node* find(const T& val)
    {
        TOfK t_of_k;
        GetInt get_i;
        Comp compare;
        size_t hash_pos =  get_i(t_of_k(val)) % _hs.size();
        Node* cur = _hs[hash_pos];
        while(cur)
        {
            if(compare(t_of_k(cur->_val), t_of_k(val)))
            {
                return cur;
            }
            cur = cur->_next;
        }
        return cur;
    }

    bool erase(const T& val)
    {
        TOfK t_of_k;
        GetInt get_i;
        Comp compare;
        size_t hash_pos =  get_i(t_of_k(val)) % _hs.size();
        Node* cur = _hs[hash_pos];
        Node* prev = _hs[hash_pos];
        while(cur)
        {
            if(compare(t_of_k(cur->_val), t_of_k(val)))
            {
                if(cur == _hs[hash_pos])
                    _hs[hash_pos] = cur->_next;
                else
                    prev->_next = cur->_next;

                delete cur;
                --_n;
                return true;
            }
            prev = cur;
            cur = cur->_next;
        }
        return false;
    }
private:
    vector<Node*> _hs;
    size_t _n = 0;

};

//#include <iostream>
//#include <vector>
//using namespace std;
////我们设计一个哈希结构，必须要清楚什么是哈希
////哈希是一种映射的结构，值与位置的映射
////而哈希表的底层为vector
//enum status //存储节点的状态
//{
//    Empty,
//    Exist,
//    Delete
//};
//
//template <class K>
//struct HashNode
//{
//    K _data;
//    status _sta = Empty;
//};
//
////仿函数
//template <class K>
//class Getint
//{
//public:
//    size_t operator()(const K& data)
//    {
//        return (size_t)data;
//    }
//};
////特化，特别实例化
//template<>
//class Getint<string>
//{
//public:
//    size_t operator()(const string& str)
//    {
//        int ascii = 0;
//        for(auto&e : str)
//        {
//            ascii += e;
//            ascii *= 131;
//        }
//        return ascii;
//    }
//};
//template <class K, class Getint = Getint<K>>
//class HashTable
//{
//public:
//    typedef HashNode<K> Node;
//    HashTable()
//    {
//        _kt.resize(10);
//    }
//
//    HashTable(const int& size)
//    {
//        _kt.resize(size);
//    }
//
//
//    bool erase(const K& data)
//    {
//        HashNode<K>* ret = find(data);
//        if(ret)
//        {
//            --_n;
//            ret->_sta = Delete;
//            return true;
//        }
//        return false;
//    }
//
//    bool insert(const K& data)
//    {
//        //拒绝重复值
//        if(find(data))
//            return false;
//
//        if((double)_n / (double)_kt.size() >= 0.7)
//        {
//            HashTable<K, Getint> new_kt(2 * _kt.size());
//
//            for(auto& e : _kt)
//            {
//                if(e._sta == Exist)
//                {
//                    new_kt.insert(e._data);
//                }
//            }
//            _kt.swap(new_kt._kt);
//        }
//
//        Getint getint;
//        int hash_pos = getint(data) % _kt.size();
//        while(_kt[hash_pos]._sta == Exist)
//        {
//            ++hash_pos;
//            hash_pos %= _kt.size();
//        }
//        _kt[hash_pos]._data = data;
//        _kt[hash_pos]._sta = Exist;
//        ++_n;
//        return true;
//    }
//
//    HashNode<K>* find(const K& data)
//    {
//        Getint getint;
//        int hash_pos = getint(data) % _kt.size();
//        while(_kt[hash_pos]._sta != Empty)
//        {
//            if(_kt[hash_pos]._sta == Exist && _kt[hash_pos]._data == data)
//                return &_kt[hash_pos];
//
//            ++hash_pos;
//            hash_pos %= _kt.size();
//        }
//        return nullptr;
//    }
//private:
//    vector<Node> _kt;
//    size_t _n = 0; //记录哈希表中的有效数据个数
//};#include <iostream>
#include <cassert>
using namespace std;
//////////////////////////////////
//我们在创造AVL树之前，先要把AVL树节点创造出来，要明确的是在AVLTreeNode类外
//我们还是需要使用到节点里面的内容，所以这里定义为struct类，默认权限为public
template <class T>
struct AVLTreeNode
{
    AVLTreeNode(const T& data)
        : _left(nullptr)
        , _right(nullptr)
        , _parent(nullptr)
        , _bf(0)
        , _data(data)
    {}
    AVLTreeNode<T>* _left;
    AVLTreeNode<T>* _right;
    AVLTreeNode<T>* _parent;
    int _bf;    //用_bf来记录树节点的左右子树高度差
    T _data;
};
///////////////////////////////////////
//创造完AVLTreeNode后，可以开始创造AVLTree
//需要注意的是，我们在日常使用AVL树时，只需要使用其成员函数，并不需要用成员变量
//所以设定为class类，成员函数权限为public，成员函数权限为private

template <class K, class Comp>
class AVLTree
{
public:
    //成员函数
    //插入函数
    bool insert(const K& data)
    {
        //这里插入规则与二叉搜索树一致
        //空树
        if(_root == nullptr)
        {
            _root = new Node(data);
            //创建失败
            if(_root == nullptr)
            {
                perror("new error");
                return false;
            }
            return true;
        }
        //不为空树
        else
        {
            Node* cur = _root;  //遍历找到插入的位置
            Node* parent = _root; //记录插入位置的父亲节点位置
            while(cur)
            {
                if(comp(cur->_data) > comp(data))  //插入值小于节点值：去左子树插入
                {
                    parent = cur;
                    cur = cur->_left;
                }
                else if(comp(cur->_data) < comp(data)) //插入值大于节点值：去右子树插入
                {
                    parent = cur;
                    cur = cur->_right;
                }
                else //插入值等于节点值：插入失败
                {
                    perror("insert a same data");
                    return false;
                }
            }

            //找到插入位置了，创造新节点
            Node* newnode = new Node(data);

            if(comp(parent->_data) > comp(data)) //新节点的值比父亲的值小，插入父亲的左侧
            {
                parent->_left = newnode;
            }
            else                     //新节点的值比父亲的值大，插入父亲的右侧
            {
                parent->_right = newnode;
            }
            newnode->_parent = parent;

            //更新平衡因子bf
            UpdateBF(newnode, parent);
            return true;
        }
    }

    //遍历
    void InOrder()
    {
        _InOrder(_root);
    }

    //判断是否为AVL树
    bool IsBalance()
    {
        int height = 0;
        return _IsBalance(_root, height);
    }
private:
    typedef AVLTreeNode<K> Node;
    Node* _root = nullptr;
    //以下成员函数不希望被外部看到，所以设为private

    //判断是否是AVL树
    bool _IsBalance(Node* root, int& height)
    {
        if (root == nullptr)
        {
            height = 0;
            return true;
        }

        int leftHeight = 0, rightHeight = 0;
        if (!_IsBalance(root->_left, leftHeight)
            || !_IsBalance(root->_right, rightHeight))
        {
            return false;
        }

        if (abs(rightHeight - leftHeight) >= 2)
        {
            cout <<root->_data<<"不平衡" << endl;
            return false;
        }

        if (rightHeight - leftHeight != root->_bf)
        {
            cout << root->_data <<"平衡因子异常" << endl;
            return false;
        }

        height = leftHeight > rightHeight ? leftHeight + 1 : rightHeight + 1;

        return true;
    }

    //遍历
    void _InOrder(Node* root)
    {
        if (root == nullptr)
            return;

        _InOrder(root->_left);
        cout << comp(root->_data)  << " ";
        _InOrder(root->_right);
    }

    //左旋转
    void RotationL(Node* parent, Node* cur)
    {
       Node* cleft = cur->_left;
       parent->_right = cleft;

       //cleft不为空，则需要链接其父亲，为空，则不用链接
       if(cleft)
           cleft->_parent = parent;

       cur->_left = parent;
       //
       Node* pparent = parent->_parent;
       parent->_parent = cur;

       if(parent == _root) //当parent就是根，旋转之后，cur就为根
       {
           _root = cur;
           cur->_parent = nullptr;
       }
       else //如果parent不是根，则需要判断parent在其父亲的左节点还是右节点
       {
           if(pparent->_left == parent)
           {
               pparent->_left = cur;
           }
           else
           {
               pparent->_right = cur;
           }
           cur->_parent = pparent;
       }

        //旋转之后，parent和cur的平衡因子都为0，不影响上层节点
        parent->_bf = 0;
        cur->_bf = 0;
    }

    //右旋转
    void RotationR(Node* parent, Node* cur)
    {
        Node* cright = cur->_right;
        parent->_left = cright;

        //cright存在，则链接其父亲到parent，不存在，不链接
        if(cright)
            cright->_parent = parent;

        cur->_right = parent;
        Node* pparent = parent->_parent;
        parent->_parent = cur;

        if(parent == _root) //当parent就是根，旋转之后，cur就为根
        {
            _root = cur;
            cur->_parent = nullptr;
        }
        else //如果parent不是根，则需要判断parent在其父亲的左节点还是右节点
        {
            if(pparent->_left == parent)
            {
                pparent->_left = cur;
            }
            else
            {
                pparent->_right = cur;
            }
            cur->_parent = pparent;
        }

        //旋转之后，parent和cur的平衡因子都为0，不影响上层节点
        parent->_bf = 0;
        cur->_bf = 0;
    }

    //左右旋转
    void RotationLR(Node* parent, Node* cur)
    {
        Node* cright = cur->_right;
        int bf = cright->_bf;

        RotationL(cur, cright);
        RotationR(parent, cright);

        if(bf == 1)
        {
            parent->_bf = 0;
            cright->_bf = 0;
            cur->_bf = -1;
        }
        else if(bf == -1)
        {
            parent->_bf = 1;
            cur->_bf = 0;
            cright->_bf = 0;
        }
        else
        {
            parent->_bf = 0;
            cur->_bf = 0;
            cright->_bf = 0;
        }
    }

    //右左旋转
    void RotationRL(Node* parent, Node* cur)
    {
        Node* cleft = cur->_left;
        int bf = cleft->_bf;

        RotationR(cur, cleft);
        RotationL(parent, cleft);

        if(bf == 1)
        {
            parent->_bf = -1;
            cleft->_bf = 0;
            cur->_bf = 0;
        }
        else if(bf == -1)
        {
            parent->_bf = 0;
            cur->_bf = 1;
            cleft->_bf = 0;
        }
        else
        {
            parent->_bf = 0;
            cur->_bf = 0;
            cleft->_bf = 0;
        }
    }

    //更新平衡因子
    void UpdateBF(Node*& cur, Node*& parent)
    {
        while(parent)
        {
            //我们在插入之前，parent的平衡因子可能为三种情况
            // 1、0、-1
            if(parent->_left == cur) //插入的节点在父亲的左边，bf--
            {
                --parent->_bf;
            }
            else //插入的节点在父亲的右边，bf++
            {
                ++parent->_bf;
            }

            //更新完平衡因子之后，parent的bf值可能为：2，1，0，-1，-2

            if(parent->_bf == 0)
            //说明parent在插入之前的bf为1或-1，以parent为根的左右子树高度差1
            //新增节点之后，也并不会影响整颗树的bf，只会让以parent为根的左右子树高度差更新为0
            {
                break;
            }
            else if(parent->_bf == -1 || parent->_bf == 1)
            //说明parent在插入之前的bf == 0，是AVL树，但是插入之后，会影响整体的高度
            //所以要依次向上更新
            {
                cur = parent;
                parent = cur->_parent;
            }
            else if(parent->_bf == 2 || parent->_bf == -2)
            //parent的平衡因子超过1，破坏了AVL树的规则，需要进行旋转
            //但是有4种旋转的情况
            {
                //情况1：左旋转
                if(parent->_bf == 2 && cur->_bf == 1)
                {
                    RotationL(parent, cur);
                }
                //情况2：右左旋转
                else if(parent->_bf == 2 && cur->_bf == -1)
                {
                    RotationRL(parent, cur);
                }
                //情况3：右旋转
                else if(parent->_bf == -2 && cur->_bf == -1)
                {
                    RotationR(parent, cur);
                }
                //情况4：左右旋转
                else if(parent->_bf == -2 && cur->_bf == 1)
                {
                    RotationLR(parent, cur);
                }
                else;

                //旋转结束、不需要更新
                break;
            }
            else
            {
                //平衡因子有问题
                assert(false);
            }

        }
    }
};
template <class K>
class AVL
{
public:
    class Comp
    {
    public:
        K& operator()(const K& data)
        {
            return data;
        }
        K& operator()(const pair<const K, V>& kv)
        {
            return kv.first;
        }
    };
private:
    AVLTree<K, Comp> avl_tree;
};














//实现红黑树，首先要确定红黑树的节点，其次再实现树结构
#include <iostream>
#include <cassert>
#include <stack>
using namespace std;
//红黑树的节点应该包含
//1. 存放的值；2.指向左右子树的指针 3.存放节点颜色 4. 指向父亲的指针
//红黑树节点的实现，必须为public，我们需要在红黑树类中使用RBTreeNode的成员变量
//////////////////////////////////////////////////
////////////////////RBTreeNode////////////////////
enum Color
{
    red,
    black
};
template <class V>
struct RBTreeNode
{
    RBTreeNode(const V& data)
        : _data(data)
        , _left(nullptr)
        , _right(nullptr)
        , _parent(nullptr)
        , _color(red)     ///插入的新节点默认是红色节点，保证每条路径的黑色节点数目相同
    {}

    V _data;
    RBTreeNode<V>* _left;
    RBTreeNode<V>* _right;
    RBTreeNode<V>* _parent;
    Color _color;
};
///////////////////////////////////////////////////
template <class V>
class RBTree_Iterator
{
public:
    typedef RBTreeNode<V> Node;
    typedef RBTree_Iterator<V> Self;

    RBTree_Iterator(Node* node)
        : _node(node)
    {}
    
    //内置类型
    V& operator*()
    {
        return _node->_data;   
    }
    
    //自定义类型
    V* operator->()
    {
        return &_node->_data;
    }
    
    bool operator==(const Self& it)
    {
        return _node == it._node;
    }

    bool operator!=(const Self& it)
    {
        return _node != it._node;
    }

    //前置++
    Self& operator++()
    {
        if(_node == nullptr)
        {
            cout << "错误" << endl;
            assert(false);
            return *this;
        }
        //右子树不为空，下一个元素为右子树的最左节点
        if(_node->_right)
        {
            _node = _node->_right;
            while(_node->_left)
            {
                _node = _node->_left;
            }
            return *this;
        }
        //右子树为空
        else
        {
            while(_node->_parent) //到根结点结束
            {
                //当前节点为父亲的左节点，则父亲就是下一个元素
                if(_node == _node->_parent->_left)
                {
                    _node = _node->_parent;
                    return *this;
                }
                    //为右节点，则表明以父节点为根的子树已经访问完了，往上查找
                else
                {
                    _node = _node->_parent;
                }
            }
            _node = nullptr;
        }
        return *this;
    }

    //后置++
    Self operator++(int)
    {
        Self copy = *this;
        ++(*this);
        return copy;
    }
    Self& operator--()
    {
        //end()
        if(_node == nullptr)
        {

        }
        //左子树不为空，则上一个元素为左子树的最右节点
        if(_node->_left)
        {
            _node = _node->_left;
            while(_node->_right)
            {
                _node = _node->_right;
            }
            return *this;
        }
        //左子树为空，当前子树已经访问过
        else
        {
            while(_node->_parent)
            {
                if(_node == _node->_parent->_right)
                {
                    _node = _node->_parent;
                    return *this;
                }
                else
                {
                    _node = _node->_parent;
                }
            }
            _node = nullptr;
            return *this;
        }

    }

    Self operator--(int)
    {
        Self copy = *this;
        --(*this);
        return copy;
    }
private:
    Node* _node;
};
///////////////////////////////////////////////////
//实现完RBTreeNode后，开始实现RBTree，而RBTree只希望被访问成员函数
//所以成员函数public，成员变量private
template <class K, class V, class KeyOfVal>
class RBTree
{
public:
    typedef RBTreeNode<V> Node;
    typedef RBTree_Iterator<V> iterator;

    //iterator begin
    iterator begin()
    {
        Node* cur = _root;
        while(cur && cur->_left)
        {
            cur = cur->_left;
        }
        return iterator(cur);
    }

    //iterator end
    iterator end()
    {
        return iterator(nullptr);
    }

    //插入节点
    bool insert(const V& data)
    {
        //空树
        if(_root == nullptr)
        {
            _root = new Node(data);
            //创建失败
            if(_root == nullptr)
            {
                perror("new error");
                return false;
            }
            //创建成功，根结点必须为黑色节点
            _root->_color = black;
            return true;
        }
        //不为空树
        else
        {
            Node* cur = _root;
            Node* parent = cur;
            KeyOfVal kov;
            while(cur)
            {
                if(kov(cur->_data) > kov(data))
                {
                    parent = cur;
                    cur = cur->_left;
                }
                else if(kov(cur->_data) < kov(data))
                {
                    parent = cur;
                    cur = cur->_right;
                }
                else
                {
                    perror("insert a same data, insert error");
                    return false;
                }
            }

            cur = new Node(data);
            if(kov(parent->_data) > kov(data))
            {
                parent->_left = cur;
            }
            else
            {
                parent->_right = cur;
            }
            cur->_parent = parent;
            //////////////////////////
            //判断颜色问题
            AssertColor(parent, cur);
            return true;
        }
        
    }
private:
    Node* _root = nullptr;
    //递归版本
    bool CheckNumB_R(Node* root, int num, int count)
    {
        if(root == nullptr)
        {
            if(num != count)
                return false;
            return true;
        }

        if(root->_color == black)
            ++count;

        return CheckNumB_R(root->_left, num, count) && CheckNumB_R(root->_right, num, count);
    }
    //非递归版本
    bool CheckNumB(Node* root)
    {
        vector<Node*> check; //检查是否右子树已经遍历过了，要记录所有走过的右侧的节点
        stack<Node*> s;      //存路径
        Node* cur = root;
        Node* pre = nullptr;
        int num = 0;         //记录黑色节点的个数
        int copy = -1;       //记录前一条路径的黑色节点的个数

        while(cur || !s.empty())
        {
            int flag = 0;

            while(cur)  //遍历每条路径
            {
                if(cur->_color == black)
                {
                    ++num;
                }
                s.push(cur);
                cur = cur->_left;
                flag = 1;
            }

            if(flag == 1) //说明走的路径是新的
            {
                if(copy != -1)
                {
                    if(copy != num) //前一个路径的黑色节点个数不等于当前路径的黑色节点个数，不满足条件，返回false
                        return false;
                }
                copy = num;
            }

            if(s.top()->_right == nullptr || CheckRepeated(check, s.top()->_right))  //右子树为空 / 右子树走过了，路径结束，换路径
            {
                if(s.top()->_color == black)
                {
                    --num;
                }
                s.pop();
            }
            else //右子树不为空，且没有走过，就去遍历右子树
            {
                cur = s.top()->_right;
                pre = cur;
                check.push_back(pre);
            }
        }
        //遍历完每条路径后，黑色节点个数都相等
        return true;

    }
    //检查右子树是否已经遍历过了
    bool CheckRepeated(vector<Node*>& check, Node*& pre)
    {
        for(auto e : check)
        {
            if(pre == e)
            {
                return true;
            }
        }
        return false;
    }


    //检查根是否为黑色
    bool CheckRoot()
    {
        if(_root == nullptr)
            return true;

        return _root->_color == black;
    }

    //检查是否有连续的红色节点
    bool CheckColor(Node* root)
    {
        if(root == nullptr)
            return true;
        return CheckColor(root->_left)
               && CheckColor(root->_right)
               && (root->_color == black || root->_parent->_color == black);
    }

    void AssertColor(Node*& parent, Node*& cur)
    {

        while(parent && parent != _root)
        {
            Node* grandfather = parent->_parent;
            Node* uncle = (parent == grandfather->_left) ? grandfather->_right : grandfather->_left;
            //插入位置的父亲为红色节点，需要处理
            if(cur->_color == red && parent->_color == red)
            {
                //叔叔存在，且为红
                if(uncle && uncle->_color == red)
                {
                    parent->_color = uncle->_color = black;
                    grandfather->_color = red;

                    cur = grandfather;
                    parent = cur->_parent;
                }
                    //叔叔存在,且为黑 / 叔叔不存在  旋转+变色
                else
                {
                    if(uncle == grandfather->_left)
                    {
                        if(cur == parent->_right)
                        {
                            RotationL(grandfather);
                            parent->_color = black;
                            grandfather->_color = red;
                        }
                        else
                        {
                            RotationR(parent);
                            RotationL(grandfather);
                            cur->_color = black;
                            grandfather->_color = red;
                        }
                    }
                    else
                    {
                        if(cur == parent->_left)
                        {
                            RotationR(grandfather);
                            parent->_color = black;
                            grandfather->_color = red;
                        }
                        else
                        {
                            RotationL(parent);
                            RotationR(grandfather);
                            cur->_color = black;
                            grandfather->_color = red;
                        }
                    }
                    break;
                }
            }
                //插入位置的父亲为黑色节点，不需要处理
            else
            {
                break;
            }
        }

        _root->_color = black;
    }
    void RotationL(Node* parent)
    {
        Node* pR = parent->_right;
        Node* pRL = pR->_left;

        parent->_right = pRL;
        if(pRL)
            pRL->_parent = parent;
        pR->_left = parent;
        Node* ppnode = parent->_parent;
        parent->_parent = pR;

        if(parent == _root)
        {
            _root = pR;
            pR->_parent = nullptr;
        }
        else
        {
            if(ppnode->_left == parent)
                ppnode->_left = pR;
            else
                ppnode->_right = pR;
            pR->_parent = ppnode;
        }

    }
    void RotationR(Node* parent)
    {
        Node* pL = parent->_left;
        Node* pLR = pL->_right;

        parent->_left = pLR;
        if(pLR)
            pLR->_parent = parent;
        pL->_right = parent;
        Node* ppnode = parent->_parent;
        parent->_parent = pL;

        if(_root == parent)
        {
            _root = pL;
            pL->_parent = nullptr;
        }
        else
        {
            if(ppnode->_left == parent)
                ppnode->_left = pL;
            else
                ppnode->_right = pL;
            pL->_parent = ppnode;
        }

    }
};

















#pragma once
#include "HashTable.h"
namespace wyd
{
    template <class K, class V, class GetInt = GetInt<V>>
    class unordered_map
    {
        class MapOfKey
        {
        public:
            const K& operator()(const pair<K, V>& kv)
            {
                return kv.first;
            }
        };
    public:
        typedef typename HashList<K, pair<K, V>, MapOfKey, GetInt>::iterator iterator;
        iterator begin()
        {
            return _h.begin();
        }
        iterator end()
        {
            return _h.end();
        }
        bool insert(const pair<K, V>& kv)
        {
            return _h.insert(kv);
        }
        bool find(const pair<K, V>& kv)
        {
            return _h.find(kv);
        }
        bool erase(const pair<K, V>& kv)
        {
            return _h.erase(kv);
        }

    private:
        HashList<K, pair<K, V>, MapOfKey, GetInt> _h;
    };
}#pragma once
#include "HashTable.h"

namespace wyd
{
    template <class K, class GetInt = GetInt<K>>
    class unordered_set
    {
        class SetOfKey
        {
        public:
            const K& operator()(const K& key)
            {
                return key;
            }
        };
    public:
        typedef typename HashList<K, K, SetOfKey, GetInt>::iterator iterator;
        iterator begin()
        {
            return _h.begin();
        }
        iterator end()
        {
            return _h.end();
        }
        bool insert(const K& key)
        {
            return _h.insert(key);
        }
        bool find(const K& key)
        {
            return _h.find(key);
        }
        bool erase(const K& key)
        {
            return _h.erase(key);
        }
    private:
        HashList<K, K, SetOfKey, GetInt> _h;
    };
}//模拟实现map
#include "NewRBTree.h"
template <class K, class V>
class mymap
{
    struct MapKeyOfT
    {
        const K& operator()(const pair<K, V>& kv)
        {
            return kv.first;
        }
    };
public:
    typedef typename RBTree<K, pair<K, V>, MapKeyOfT>::iterator iterator;
    iterator begin()
    {
        return _t.begin();
    }
    iterator end()
    {
        return _t.end();
    }
    bool Insert(const pair<K, V>& kv)
    {
        return _t.insert(kv);
    }
private:
    RBTree<K, pair<K, V>, MapKeyOfT> _t;
};
void test_map1()
{
    mymap<int, int> m;
    int a[] = { 4, 2, 6, 1, 3, 5, 15, 7, 16, 14 };
    for (auto e : a)
    {
        m.Insert(make_pair(e, e));
    }

   mymap<int, int>::iterator it = m.begin();
    while (it != m.end())
    {
        //it->first += 100;
        it->second += 100;

        cout << it->first << ":" << it->second << endl;
        ++it;
    }
    cout << endl;
}
//模拟实现set
#include "NewRBTree.h"
template <class K>
class myset
{
public:
   bool Insert(const K& val)
   {
       return _rb_tree.insert(val);
   }
private:
    struct FirstVal
    {
        const K& operator()(const K& val)
        {
            return val;
        }
    };
    RBTree<K, K, FirstVal> _rb_tree;
};// 请模拟实现红黑树的插入--注意：为了后序封装map和set，本文在实现时给红黑树多增加了一个头结点
#include <iostream>
using namespace std;
enum Color
{
    red,
    black
};
template <class T>
struct RBTreeNode
{
    RBTreeNode(const T& data = T())
        : _left(nullptr)
        , _right(nullptr)
        , _parent(nullptr)
        , _data(data)
        , _color(red)
    {}
    RBTreeNode<T>* _left;
    RBTreeNode<T>* _right;
    RBTreeNode<T*> _parent;
    T _data;
    Color _color;
};
template<class T>
class RBTree
{
    typedef RBTreeNode<T> Node;
public:
    RBTree()
    {
        _pHead = new Node;
        _pHead->_pLeft = _pHead;
        _pHead->_pRight = _pHead;
    }

    // 在红黑树中插入值为data的节点，插入成功返回true，否则返回false
    // 注意：为了简单起见，本次实现红黑树不存储重复性元素
    bool Insert(const T& data)
    {
        //没有根结点
        Node* root = _pHead->_parent;
        if(root == nullptr)
        {
            root = new Node(data);
            root->_parent = _pHead;
            root->_color = black;
        }
        //有根结点
        else
        {
            Node* cur = root;
            Node* parent = root;
            while(cur)
            {
                if(cur->_data > data)
                {
                    parent = cur;
                    cur = cur->_left;
                }
                else if(cur->_data < data)
                {
                    parent = cur;
                    cur = cur->_right;
                }
                else
                {
                    return false;
                }
            }

            Node* newnode = new Node(data);
            if(parent->_data > data)
            {
                parent->_left = newnode;
            }
            else
            {
                parent->_right = newnode;
            }
            newnode->_parent = parent;

            //判断颜色
            AssertColor(parent, newnode);
        }

        //更新最左节点
        _pHead->_left = LeftMost();
        //更新最右节点
        _pHead->_right = RightMost();
        return true;
    }

    // 检测红黑树中是否存在值为data的节点，存在返回该节点的地址，否则返回nullptr
    Node* Find(const T& data)
    {
        Node* cur = GetRoot();
        while(cur)
        {
            if(cur->_data > data)
            {
                cur = cur->_left;
            }
            else if(cur->_data < data)
            {
                cur = cur->_right;
            }
            else
            {
                return cur;
            }
        }
        return nullptr;
    }


    // 检测红黑树是否为有效的红黑树，注意：其内部主要依靠_IsValidRBTRee函数检测
    bool IsValidRBTRee()
    {

    }
private:
    //判断颜色
    void AssertColor(const Node*& parent, const Node*& cur)
    {
        while(cur != _pHead->_parent)
        {
            //父亲是黑色节点，不会影响树的性质
            if(parent->_color == black)
            {
                return;
            }
            //父亲为红色节点，需要改变颜色
            else
            {
                Node* g_parent = parent->_parent;
                Node* uncle = g_parent->_left == parent ? g_parent->_right : g_parent->_left;
                //叔叔存在且为红
                if(uncle && uncle->_color == red)
                {
                    parent->_color = uncle->_color = black;
                    g_parent->_color = red;
                    cur = g_parent;
                    parent = cur->_parent;
                }
                    //叔叔存在且为黑 || 叔叔不存在
                else
                {

                }
            }
        }

        _pHead->_parent = black;
    }

    bool _IsValidRBTRee(Node* pRoot, size_t blackCount, size_t pathBlack)
    {

    }
    // 左单旋
    void RotateL(Node* pParent)
    {

    }
    // 右单旋
    void RotateR(Node* pParent)
    {

    }
    // 为了操作树简单起见：获取根节点
    Node*& GetRoot()
    {
        return _pHead->_parent;
    }
    // 获取红黑树最左侧节点
    Node* LeftMost()
    {
        Node* cur = _pHead->_parent;
        while(cur->_left)
        {
            cur = cur->_left;
        }
        return cur;
    }

    // 获取红黑树最右侧节点
    Node* RightMost()
    {
        Node* cur = _pHead->_parent;
        while(cur->_right)
        {
            cur = cur->_right;
        }
        return cur;
    }
private:
    Node* _pHead;
};//#include <iostream>
//using namespace std;
////int main()
////{
//////    srand(3);
//////    int count = 100;
//////    map<int, int> m;
//////    while(count--)
//////    {
//////        int r = rand();
//////        ++m[r];
//////    }
////    int i = 0;
////    i = RAND_MAX;
////    cout << i << endl;
//////    for(auto& e : m)
//////    {
//////        cout << e.first << " " ;
////////        if(e.second > 1)
////////        {
////////            ++i;
////////        }
//////    }
//////    cout << i << endl;
////    return 0;
////}
//#include <set>
//#include <unordered_set>
// int main()
//{
//	const size_t N = 10000;
//
//	unordered_set<int> us;  //容器1
//	set<int> s;             //容器2
//
//	vector<int> v;          //使用vector保存插入的数据
//	v.reserve(N);           //防止多次扩容，造成消耗，提前一次预留N个空间
//
//	srand(time(nullptr));   //种随机数种子，使用time做参数，可以保证每次运行，都是不一样的
//
//	for (size_t i = 0; i < N; ++i)
//	{
//		v.push_back(rand()); // N比较大时，重复值比较多
//		//v.push_back(rand()+i); // 重复值相对少
//		//v.push_back(i); // 没有重复，有序
//	}
//
//	//测试容器插入的性能
//	size_t begin1 = clock();
//	for (auto& e : v)
//	{
//		s.insert(e);
//	}
//	size_t end1 = clock();
//	cout << "set insert:" << end1 - begin1 << endl;
//
//	size_t begin2 = clock();
//	for (auto& e : v)
//	{
//		us.insert(e);
//	}
//	size_t end2 = clock();
//	cout << "unordered_set insert:" << end2 - begin2 << endl;
//
//    //测试容器查找的性能
//	size_t begin3 = clock();
//	for (auto& e : v)
//	{
//		s.find(e);
//	}
//	size_t end3 = clock();
//	cout << "set find:" << end3 - begin3 << endl;
//
//	size_t begin4 = clock();
//	for (auto& e : v)
//	{
//		us.find(e);
//	}
//	size_t end4 = clock();
//	cout << "unordered_set find:" << end4 - begin4 << endl << endl;
//
//	cout <<"插入数据个数："<< s.size() << endl;
//	cout <<"插入数据个数：" << us.size() << endl << endl;
//
//    //测试容器删除的性能
//	size_t begin5 = clock();
//	for (auto& e : v)
//	{
//		s.erase(e);
//	}
//	size_t end5 = clock();
//	cout << "set erase:" << end5 - begin5 << endl;
//
//	size_t begin6 = clock();
//	for (auto e : v)
//	{
//		us.erase(e);
//	}
//	size_t end6 = clock();
//	cout << "unordered_set erase:" << end6 - begin6 << endl << endl;
//
//	return 0;
//}
//#include <iostream>
//#include <cstdlib>
//
//using namespace std;
//int main()
//{
//    int N = 10;
//    srand(1);
//    for(int i = 0; i < N; ++i)
//    {
//        cout << rand() << endl;
//    }
//    return 0;
//}
//#include "my_unorder_Map.h"
//#include "my_unorder_Set.h"
//void Test1()
//{
//    wyd::unordered_set<int> s;
//    int arr[] = {1,11,111,2,22,
//                 12,21,3,4,5,
//                 15,45,1,11,1,
//                 1,1,1,1,1};
//    for(auto e : arr)
//    {
//        s.insert(e);
//    }
//    for(auto e : s)
//    {
//        cout << e << " ";
//    }
//    cout << endl;
//}
//int main()
//{
//    size_t i = (unsigned )-1;
//    cout << i << endl;
//    Test1();
//    wyd::unordered_map<int, int> m;
//    int arr[] = {1,11,111,2,22,
//                 12,21,3,4,5,
//                 15,45,1,11,1,
//                 1,1,1,1,1};
//    for(auto e : arr)
//    {
//        ++m[e];
//    }
//    for(auto e : m)
//    {
//        cout << e.first << ":" << e.second << endl;
//    }
//    OpenHash::HashBucket<int> hash;
//    int arr[] = {12,2,3,33,4,
//                 44,5,55,6,16
//                 ,26,11,1,17};
//    for(auto e : arr)
//    {
//        hash.Insert(e);
//    }
//    hash.Erase(55);
//    hash.Erase(17);
//    int a = 0;
//    return 0;
//}
//#include "bitset.h"
//void Test()
//{
//    wyd::bitset<10000> b;
//    srand(time(nullptr));
//    for(int i = 0; i < 100; ++i)
//    {
//        int r = rand() % 10000;
//        b.set(r);
//    }
//
//    for(int i = 0; i < 10000; ++i)
//    {
//        if(b.test(i))
//            cout << i << endl;
//    }
//    int N = 10000;
//    for(int i = 0; i < N; ++i)
//    {
//        size_t r = rand() % 1000;
//        b.set(r);
//    }
//    for(int i = 0; i < N; ++i)
//    {
//        size_t r = rand() % 0xffffffff;
//        if(b.test(r))
//            cout << r << " ";
//    }
//    cout << endl;
//
//
//}
//void Test2()
//{
//    wyd::bit_two_set<100> ts;
//    int arr1[] = {1,2,3,12,4,5,77
//                 ,88,9,54,34,56};
//    int arr2[] = {99,1,2,
//                  3,12,65,44,22};
//
//    for(auto i : arr1)
//    {
//        ts.set(i);
//    }
//    for(auto i : arr2)
//    {
//        ts.set(i);
//    }
//
//    for(int i = 0; i < 100; ++i)
//    {
//        if(ts.test(i))
//            cout << i << " ";
//    }
//    cout << endl;
//
//}
//void Test3()
//{
//    wyd::bitset<50> b1;
//    wyd::bitset<50> b2;
//    int arr1[] = {1,2,3,12,4,5,77
//            ,88,9,54,34,56};
//    int arr2[] = {99,1,2,
//                  3,12,65,44,22};
//
//    for(auto i : arr1)
//    {
//        if(i < 50)
//            b1.set(i);
//    }
//    for(auto i : arr2)
//    {
//        if(i < 50)
//            b2.set(i);
//    }
//    for(int i = 0; i < 100; ++i)
//    {
//        if(b1.test(i) && b2.test(i))
//            cout << i << " ";
//    }
//    cout << endl;
//
//
//
//}
//#include <vector>
//#include "BinarySearchTree.h"
//int& func()
//{
//    static int a = 1;
//    return a;
//}
//int main()
//{
//    int&& i = 10;
//    int& b = i;
//    cout << b;
//    const int c = 3;
//    cout << &c << endl;
//    cout << &func << endl;
//
//    int a = 0;
//    const int* p1 = &a;
//    int* const p2 = nullptr;
//    cout << typeid(p1).name() << endl;
//    cout << typeid(p2).name() << endl;
//    BSTree<int> tree;
//    srand(time(nullptr));
//    int N = 1000;
//    for(int i = 0; i < N; ++i)
//    {
//        int r = rand() % 10000;
//        tree.insert(r);
//    }
//    tree.inorder();
//    cout << tree.size() << endl;
//    int arr[] = {10,2,3,6,
//                 5,8,77,66};
//    vector<string> str = {"123", "66", "vector", "string"};
//    for(auto& e :str)
//    {
//        tree.insert(e);
//    }
////    cout << tree.height() << endl;
////    cout << tree.size() << endl;
//    tree.inorder();
////    tree.erase("123");
//    cout << tree.find("vector")->_val << endl;
////    cout << tree.size() << endl;
//    tree.inorder();
//////    tree.erase(2);
////    tree.inorder();
//    tree.erase(6);
//    tree.erase(8);
//    tree.erase(5);
//    tree.erase(10);
//    tree.erase(3);
//    tree.erase(66);
//    tree.erase(77);
//    cout << tree.size() << endl;
//    tree.inorder();
//    tree.erase(77);
//    return 0;
//}#include <iostream>
#include <vector>
#include <utility>
using namespace std;
struct Goods
{
    string _name; // 名字
    double _price; // 价格
    int _evaluate; // 评价
    Goods(const char* str, double price, int evaluate)
        :_name(str)
        , _price(price)
        , _evaluate(evaluate)
    {}
    Goods()
    {};
    void Print()
    {

    }
};
int main()
{
    int a = 10;
    char b = a;
    Goods();

    // auto f = [](Goods&& g1, Goods&& g2)
    // {
    //     cout << g1._name << g1._price << endl;
    //     cout << g2._name << g2._price << endl;
    // };

    // f({"小王子", 100, 5}, {"云烟成雨", 20, 3});

    return 0;
}
// class CompPrice
// {
// public:
//     bool operator()(const Goods& g1, const Goods& g2)
//     {
//         return g1._price > g2._price;
//     }
// };
// class CompEva
// {
// public:
//     bool operator()(const Goods& g1, const Goods& g2)
//     {
//         return g1._evaluate > g2._evaluate;
//     }
// };
// int main()
// {
//     vector<Goods> v = {{ "苹果", 2.1, 5 }, { "香蕉", 3, 4 }, 
//                        { "橙子", 2.2, 3 }, { "菠萝", 1.5, 4 } };

//     sort(v.begin(), v.end(), [](Goods& g1, Goods& g2)
//     {
//         return g1._price > g2._price;
//     });
//     for(auto e : v)
//     {
//         cout << e._name << ":" << e._price << ":" << e._evaluate << endl;;
//     }
// cout << "///////////////////////////////////////////////////" << endl;
//     sort(v.begin(), v.end(), [](Goods& g1, Goods& g2)
//     {
//         return g1._evaluate > g2._evaluate;
//     });
//     for(auto e : v)
//     {
//         cout << e._name << ":" << e._price << ":" << e._evaluate << endl;;
//     }    
// cout << "///////////////////////////////////////////////////" << endl;
//     sort(v.begin(), v.end(), [](Goods& g1, Goods& g2)
//     {
//         return g1._name > g2._name;
//     });
//    cout << "///////////////////////////////////////////////////" << endl; 
//     for(auto e : v)
//     {
//         cout << e._name << ":" << e._price << ":" << e._evaluate << endl;;
//     }
    // sort(v.begin(), v.end(), CompPrice());
    // for(auto e : v)
    // {
        // cout << e._name << ":" << e._price << ":" << e._evaluate << endl;;
    // }
    // cout << "///////////////////////////////////////////////////" << endl;
    // sort(v.begin(), v.end(), CompEva());
    // for(auto e : v)
    // {
    //     cout << e._name << ":" << e._price << ":" << e._evaluate << endl;;
    // } 
    // Goods g1 = {"wyd", 100, 5};
    // Goods g2 = {"sb", 0 , -5};
    // if(CompLess()(g1, g2))
    //     cout << g1._name << endl;
    // else
    //     // cout << g2._name << endl;
    // return 0;
// }
// using namespace std;
// template <class T>
// int test(const T& val)
// {
//     cout << val << endl;
//     return 1;
// }
// template <class...Args>
// void func(Args...args)
// {
//     int arr[] = {test(args)...};
// }
// int main()
// {
//     func('c', 1, 1.1, string("hellow"));
//     return 0;
// }

// template <class T>
// void test(const T& val) {cout << "const 左值引用" << endl;}
// template <class T>
// void test(T& val) {cout << "左值引用" << endl;}
// template <class T>
// void test(T&& val) {cout << "右值引用" << endl;}
// template <class T>
// void test(const T&& val) {cout << "const 右值引用" << endl;}

// template <class T>
// void func1(T&& val)
// {
//     test(forward<T>(val));   //使用forward保持参数原有属性
// }

// int main()
// {
//     int x = 10;
//     func1(x);
//     func1(std::move(x));

//     const int y = 10;
//     func1(y);
//     func1(std::move(y));

//     return 0;   
// }
// my::string Func1()
// {
//     my::string str = "hello CSDN";
//     //..
//     return str;
// }
// #include <iostream>
// #include <vector>
// using namespace std;
// int main()
// {
//     int x = 2, y = 1;
//     auto swap1 = [&x, &y]
//     {
//         int tmp = x;
//         cin >> x;
//         y = tmp;
//     };
//     swap1();
//     cout << x << endl;
//     cout << y << endl;
//     return 0;
// }
// void _Showlist()
// {
//     cout << "可变参数使用完" << endl;
// }
// template<class T, class...Args>
// void _Showlist(T&& val, Args&&...args)
// {
//     cout << val << endl;
//     _Showlist(args...);
// }
// template <class...Args>
// void Showlist(Args&&...args)
// {
//     _Showlist(forward<Args>(args...));
// }

// int main()
// {

//     //auto add = [](int a, int b){return a + b;};
//     //cout << add(1,2) << endl;
//     // vector<int> i;
//     // i.emplace_back(2);
//     return 0;
// }

// void _func()
// {
//     cout << "我无了" << endl;
// }
// template < class T, class...X>
// void _func(const T& val, X...x)
// {
//     cout << val << " ";
//     _func(x...);
// }

// template <class ... X>
// void func(X... x)
// {
//     _func(x...);
// }

// int main()
// {
//     int x = 3;
//     char y = 's';
//     double z = 1.1;
//     func(x, y, z);
//     return 0;
// }
// MY::string func()
// {
//     MY::string str;
//     return str;
// }
// void Test()
// {
//     MY::string str = func();

// }
// void Fun(int &x){ cout << "左值引用" << endl; }
// void Fun(const int &x){ cout << "const 左值引用" << endl; }
// void Fun(int &&x){ cout << "右值引用" << endl; }
// void Fun(const int &&x){ cout << "const 右值引用" << endl; }
// template <typename T>
// void func(T&& val)
// {
//     Fun(forward<T>(val));
// }
// int main()
// {
//     int a = 3;
//     const int b = 4;
//     func(a);
//     func(move(a));
//     func(b);
//     func(move(b));
//     return 0;
// }
//传引用，不需要拷贝
//void func1(vector<vector<int>>& darr)
//{
//    //.....
//}
////传值，需要拷贝
//void func2(vector<vector<int>> darr)
//{
//    //.....
//}
//
//vector<int>& func3(vector<int>& arr)
//{
//    //....
//    return arr; //这里的返回值就是出函数作用域还存在，可以用引用返回，减少拷贝
//}
//
//vector<int> func4(vector<int>& arr)
//{
//    //....
//    return arr; //这里就是多了个拷贝
//}
//
////两者对比，对于出作用域还存在的返回值，可以使用左值引用返回
//
//void Func1(vector<string> v_str)
//{
//    //...
//}
//
////这里必须是返回值严格出函数作用域不销毁，才可以使用左值引用返回
//vector<string>& Func3(vector<string>& L_str)
//{
//    //...
//    return L_str;
//}
//
//vector<string> Func2(vector<string>& L_str)
//{
//    //...
//    return L_str;
//}


//int main()
//{
//    vector<string> v_str = {"Hello", "CSDN"};
//
//    Func1(v_str);
//    Func1({"hello", "C++"});
//
//    Func2(v_str);
//    Func2({"hello", "C++"});

//    return 0;
//}
// 左边 = 右边
//    int a = 3;           //a为左值，3为右值
//
//    int& ar1 = a;        //左值引用 可以引用 左值
//
//    int&& ar2 = a;       //右值引用 不可以引用 左值
//    int&& ar3 = move(a); //右值引用可以 引用move后的左值
//    int&& ar4 = a;       //但是a本身的性质不变，依旧是左值
//
//    int& ar5 = 3;        //左值引用 不可以引用 右值
//    const int& ar6 = 3;  //const 左值引用 可以引用 右值
//
//    int&& ar7 = 3;       // 右值引用 可以引用 右值
//
//
//    int b = a;           //左值 可以   放在 ‘=’ 的右边
//    3 = a;               //右值 不可以 放在 ‘=’ 的左边


//c = 5;
//    b = c;

//    const int x = 10;
//   // x = 12; //虽然x不可出现在 ‘ = ’的左边
//   // const int&& y = x;   //右值引用无法引用
//    const int& z = x;    //左值引用可以引用，但必须是const，要保证权限
////                         从语法上证明，x仍为左值
//    int arr[] = {1,2,3,4,5};
//    const int a = 0;
//    int b = 8;
//    b = a;
//    const int&& c = a;
//    const int& d = a;
//
//    return 0;
//}#include <iostream>
// #include <functional>
// // #include <vector>
using namespace std;
void func()
{
    int i = 0;
    cin >> i;
    if(i < 10)
        throw i;

}
int main()
{
    try
    {
        func();   
    }
    catch(int a)
    {
        cout << "捕获异常"<< a << endl;
    }
    
    return 0;
}
// int add(int x, int y)
//     {return x + y;}
// int main()
// {
//     int x = 4;
//     int y = 7;
//     function<int(int, int)> f1 = add;
//     function<int(int, int)> f2 = [=](int, int){return x + y;};
//     cout << f1(1,2) << endl;
//     cout << f2(3,4) << endl;
//     return 0;
// }
// void spread(vector< vector<int> >& grid, int i, int j, int column_size, int line_size, int flag)
// {
//     if(i + 1 < column_size)
//         grid[i + 1][j] == 1 ? grid[i + 1][j] = 3 : flag;    
//     if(j - 1 >= 0)
//         grid[i][j - 1] == 1 ? grid[i][j - 1] = 3 : flag;
//     if(j + 1 < line_size)
//         grid[i][j + 1] == 1 ? grid[i][j + 1] = 3 : flag;
//     if(i - 1 >= 0)
//         grid[i - 1][j] == 1 ? grid[i - 1][j] = 3 : flag;    
// } 
// bool check(vector< vector<int> >& grid, int i, int j, int column_size, int line_size)
// {
//     //判断上下左右是否为0，不为0，则继续，为0就返回-1
//     if((i + 1 < column_size) && (grid[i + 1][j] != 0))
//         return false;
//     if((j - 1 >= 0) && (grid[i][j - 1] != 0 ))
//         return false;
//     if((j + 1 < line_size) && (grid[i][j + 1] != 0))
//         return false;
//     if((i - 1 >= 0) && (grid[i - 1][j] != 0))
//         return false;
//     return true;
// }
// int rotApple(vector<vector<int> >& grid) 
// {
//     int t = 0; //时间：min
//     int line_size = grid[0].size(); //列
//     int column_size = grid.size() / grid[0].size(); //行
//     int flag = 1; //没啥用，就是为了补条件表达式的

//     int count_one = 1; //计算1的个数
//     while(count_one != 0) //结束条件1 ：没有完好的苹果了   
//     { 
//         count_one = 0;
//         for(int i = 0; i < column_size; ++i) //遍历列
//         {
//             for(int j = 0; j < line_size; ++j) //遍历行
//             {
//                 //找到腐烂的苹果
//                 if(grid[i][j] == 2)
//                 {
//                     spread(grid, i ,j, column_size, line_size, flag); //腐烂传播
//                 }
//                 if(grid[i][j] == 1)
//                 {
//                     if(check(grid, i ,j, column_size, line_size)) //判断苹果四周是否为0
//                         return -1; //结束条件2:存在不会腐烂的苹果
//                     ++count_one;
//                 }
//             }
//         }

//         for(int i = 0; i < column_size; ++i)
//         {
//             for(int j = 0; j < line_size; ++j)
//             {
//                 grid[i][j] == 3 ? grid[i][j] = 2 : flag;
//             }
//         }
//         ++t;
//     }
//     return t;
// }
// class A
// {
// public:
//     A(){}
//     A(int b) = default;
// };
// int main()
// {
//     vector< vector<int> > m = {{2,1,1},{1,0,1},{1,1,1}};
//     rotApple(m);
//     return 0;
// }





























// // #include <iostream>
// // // #include <vector>
// // // #include <utility>
// // // using namespace std;
// // // struct Goods
// // // {
// // //     string _name; // 名字
// // //     double _price; // 价格
// // //     int _evaluate; // 评价
// // //     Goods(const char* str, double price, int evaluate)
// // //         :_name(str)
// // //         , _price(price)
// // //         , _evaluate(evaluate)
// // //     {}
// // //     Goods()
// // //     {};
// // //     void Print()
// // //     {

// // //     }
// // // };
// // // int main()
// // // {
// // //     int a = 10;
// // //     char b = a;
// // //     Goods();

//     // auto f = [](Goods&& g1, Goods&& g2)
//     // {
//     //     cout << g1._name << g1._price << endl;
//     //     cout << g2._name << g2._price << endl;
//     // };

//     // f({"小王子", 100, 5}, {"云烟成雨", 20, 3});

//     // return 0;
// // }
// // class CompPrice
// // {
// // public:
// //     bool operator()(const Goods& g1, const Goods& g2)
// //     {
// //         return g1._price > g2._price;
// //     }
// // };
// // class CompEva
// // {
// // public:
// //     bool operator()(const Goods& g1, const Goods& g2)
// //     {
// //         return g1._evaluate > g2._evaluate;
// //     }
// // };
// // int main()
// // {
// //     vector<Goods> v = {{ "苹果", 2.1, 5 }, { "香蕉", 3, 4 }, 
// //                        { "橙子", 2.2, 3 }, { "菠萝", 1.5, 4 } };

// //     sort(v.begin(), v.end(), [](Goods& g1, Goods& g2)
// //     {
// //         return g1._price > g2._price;
// //     });
// //     for(auto e : v)
// //     {
// //         cout << e._name << ":" << e._price << ":" << e._evaluate << endl;;
// //     }
// // cout << "///////////////////////////////////////////////////" << endl;
// //     sort(v.begin(), v.end(), [](Goods& g1, Goods& g2)
// //     {
// //         return g1._evaluate > g2._evaluate;
// //     });
// //     for(auto e : v)
// //     {
// //         cout << e._name << ":" << e._price << ":" << e._evaluate << endl;;
// //     }    
// // cout << "///////////////////////////////////////////////////" << endl;
// //     sort(v.begin(), v.end(), [](Goods& g1, Goods& g2)
// //     {
// //         return g1._name > g2._name;
// //     });
// //    cout << "///////////////////////////////////////////////////" << endl; 
// //     for(auto e : v)
// //     {
// //         cout << e._name << ":" << e._price << ":" << e._evaluate << endl;;
// //     }
//     // sort(v.begin(), v.end(), CompPrice());
//     // for(auto e : v)
//     // {
//         // cout << e._name << ":" << e._price << ":" << e._evaluate << endl;;
//     // }
//     // cout << "///////////////////////////////////////////////////" << endl;
//     // sort(v.begin(), v.end(), CompEva());
//     // for(auto e : v)
//     // {
//     //     cout << e._name << ":" << e._price << ":" << e._evaluate << endl;;
//     // } 
//     // Goods g1 = {"wyd", 100, 5};
//     // Goods g2 = {"sb", 0 , -5};
//     // if(CompLess()(g1, g2))
//     //     cout << g1._name << endl;
//     // else
//     //     // cout << g2._name << endl;
//     // return 0;
// // }
// // using namespace std;
// // template <class T>
// // int test(const T& val)
// // {
// //     cout << val << endl;
// //     return 1;
// // }
// // template <class...Args>
// // void func(Args...args)
// // {
// //     int arr[] = {test(args)...};
// // }
// // int main()
// // {
// //     func('c', 1, 1.1, string("hellow"));
// //     return 0;
// // }

// // template <class T>
// // void test(const T& val) {cout << "const 左值引用" << endl;}
// // template <class T>
// // void test(T& val) {cout << "左值引用" << endl;}
// // template <class T>
// // void test(T&& val) {cout << "右值引用" << endl;}
// // template <class T>
// // void test(const T&& val) {cout << "const 右值引用" << endl;}

// // template <class T>
// // void func1(T&& val)
// // {
// //     test(forward<T>(val));   //使用forward保持参数原有属性
// // }

// // int main()
// // {
// //     int x = 10;
// //     func1(x);
// //     func1(std::move(x));

// //     const int y = 10;
// //     func1(y);
// //     func1(std::move(y));

// //     return 0;   
// // }
// // my::string Func1()
// // {
// //     my::string str = "hello CSDN";
// //     //..
// //     return str;
// // }
// // #include <iostream>
// // #include <vector>
// // using namespace std;
// // int main()
// // {
// //     int x = 2, y = 1;
// //     auto swap1 = [&x, &y]
// //     {
// //         int tmp = x;
// //         cin >> x;
// //         y = tmp;
// //     };
// //     swap1();
// //     cout << x << endl;
// //     cout << y << endl;
// //     return 0;
// // }
// // void _Showlist()
// // {
// //     cout << "可变参数使用完" << endl;
// // }
// // template<class T, class...Args>
// // void _Showlist(T&& val, Args&&...args)
// // {
// //     cout << val << endl;
// //     _Showlist(args...);
// // }
// // template <class...Args>
// // void Showlist(Args&&...args)
// // {
// //     _Showlist(forward<Args>(args...));
// // }

// // int main()
// // {

// //     //auto add = [](int a, int b){return a + b;};
// //     //cout << add(1,2) << endl;
// //     // vector<int> i;
// //     // i.emplace_back(2);
// //     return 0;
// // }

// // void _func()
// // {
// //     cout << "我无了" << endl;
// // }
// // template < class T, class...X>
// // void _func(const T& val, X...x)
// // {
// //     cout << val << " ";
// //     _func(x...);
// // }

// // template <class ... X>
// // void func(X... x)
// // {
// //     _func(x...);
// // }

// // int main()
// // {
// //     int x = 3;
// //     char y = 's';
// //     double z = 1.1;
// //     func(x, y, z);
// //     return 0;
// // }
// // MY::string func()
// // {
// //     MY::string str;
// //     return str;
// // }
// // void Test()
// // {
// //     MY::string str = func();

// // }
// // void Fun(int &x){ cout << "左值引用" << endl; }
// // void Fun(const int &x){ cout << "const 左值引用" << endl; }
// // void Fun(int &&x){ cout << "右值引用" << endl; }
// // void Fun(const int &&x){ cout << "const 右值引用" << endl; }
// // template <typename T>
// // void func(T&& val)
// // {
// //     Fun(forward<T>(val));
// // }
// // int main()
// // {
// //     int a = 3;
// //     const int b = 4;
// //     func(a);
// //     func(move(a));
// //     func(b);
// //     func(move(b));
// //     return 0;
// // }
// //传引用，不需要拷贝
// //void func1(vector<vector<int>>& darr)
// //{
// //    //.....
// //}
// ////传值，需要拷贝
// //void func2(vector<vector<int>> darr)
// //{
// //    //.....
// //}
// //
// //vector<int>& func3(vector<int>& arr)
// //{
// //    //....
// //    return arr; //这里的返回值就是出函数作用域还存在，可以用引用返回，减少拷贝
// //}
// //
// //vector<int> func4(vector<int>& arr)
// //{
// //    //....
// //    return arr; //这里就是多了个拷贝
// //}
// //
// ////两者对比，对于出作用域还存在的返回值，可以使用左值引用返回
// //
// //void Func1(vector<string> v_str)
// //{
// //    //...
// //}
// //
// ////这里必须是返回值严格出函数作用域不销毁，才可以使用左值引用返回
// //vector<string>& Func3(vector<string>& L_str)
// //{
// //    //...
// //    return L_str;
// //}
// //
// //vector<string> Func2(vector<string>& L_str)
// //{
// //    //...
// //    return L_str;
// //}


// //int main()
// //{
// //    vector<string> v_str = {"Hello", "CSDN"};
// //
// //    Func1(v_str);
// //    Func1({"hello", "C++"});
// //
// //    Func2(v_str);
// //    Func2({"hello", "C++"});

// //    return 0;
// //}
// // 左边 = 右边
// //    int a = 3;           //a为左值，3为右值
// //
// //    int& ar1 = a;        //左值引用 可以引用 左值
// //
// //    int&& ar2 = a;       //右值引用 不可以引用 左值
// //    int&& ar3 = move(a); //右值引用可以 引用move后的左值
// //    int&& ar4 = a;       //但是a本身的性质不变，依旧是左值
// //
// //    int& ar5 = 3;        //左值引用 不可以引用 右值
// //    const int& ar6 = 3;  //const 左值引用 可以引用 右值
// //
// //    int&& ar7 = 3;       // 右值引用 可以引用 右值
// //
// //
// //    int b = a;           //左值 可以   放在 ‘=’ 的右边
// //    3 = a;               //右值 不可以 放在 ‘=’ 的左边


// //c = 5;
// //    b = c;

// //    const int x = 10;
// //   // x = 12; //虽然x不可出现在 ‘ = ’的左边
// //   // const int&& y = x;   //右值引用无法引用
// //    const int& z = x;    //左值引用可以引用，但必须是const，要保证权限
// ////                         从语法上证明，x仍为左值
// //    int arr[] = {1,2,3,4,5};
// //    const int a = 0;
// //    int b = 8;
// //    b = a;
// //    const int&& c = a;
// //    const int& d = a;
// //
// //    return 0;
// //}#include <iostream>
#include <functional>
#include <memory>
using namespace std;
// namespace my
// {
//     template <class T>
//     class shared_ptr
//     {
//     public:
//         template <class D>
//         shared_ptr(T* ptr, D del)
//             : _ptr(ptr)
//             , _count(new int(1))
//             , _del(del)
//         {}

//         shared_ptr(const shared_ptr<T>& sp)
//             : _ptr(sp._ptr)
//             , _count(sp._count)
//         {
//             ++(*_count);
//         }

//         shared_ptr<T>& operator=(const shared_ptr<T>& sp)
//         {
//             if(_ptr != sp._ptr)
//             {
//                 //赋值， sp1 = sp2，因为赋值后，sp1就不再管理自己的资源了，所以要先释放
//                 //但是此时也要通过引用计数，我们不能保证只有sp1管理这段资源
//                 _release();
//                 _ptr = sp._ptr;
//                 _count = sp._count;
//                 ++(*_count);
//             }
//             return *this;
//         }

//         ~shared_ptr()
//         {
//             cout << "~shared_ptr()" << endl;
//             _release();
//         }

//         int use_count()
//         {
//             return *_count;
//         }

//         T& operator*()
//         {
//             return *_ptr;
//         }

//         T* operator->()
//         {
//             return _ptr;
//         }

//     private:
//         T* _ptr;
//         int* _count;
//         std::function<void(T*)> _del = [](T* ptr){delete ptr;};
//         //////////////////////////////////////////////
//         void _release()
//         {
//             //当引用计数为0时，就可以释放资源
//             if(--(*_count) == 0)
//             {
//                 _del(_ptr);
//                 delete _count;
//                 _ptr = nullptr;
//                 _count = nullptr;
//             }
//         }
//     };
// }
int main()
{
    std::shared_ptr<int> sp1(new int[10], [](int* ptr){delete[] ptr;});

    return 0;
}
// namespace my
// {
//     template <class T>
//     class unique_ptr
//     {
//     public:    
//         unique_ptr(T* ptr = nullptr)
//             : _ptr(ptr)
//         {}

//         //这里仅仅是函数声明
//         //禁止拷贝构造
//         unique_ptr(const unique_ptr<T>&) = delete;
//         //禁止赋值运算符重载
//         unique_ptr<T>& operator=(const unique_ptr<T>&) = delete;

//         ~unique_ptr()
//         {
//             if(_ptr)
//                 delete _ptr;
//         }

//         T& operator*()
//         {
//             return *_ptr;
//         }

//         T* operator->()
//         {
//             return _ptr;
//         }

//     private:
//         T* _ptr;
//     };
// }
// int main()
// {
//     my::unique_ptr<int> up1(new int(3));
//     my::unique_ptr<int> up2(up1);
//     my::unique_ptr<int> up3;
//     up3 = up1;
//     return 0;
// }
// namespace my
// {
//     template <class T>
//     class auto_ptr
//     {
//     public:
//         explicit auto_ptr(T* ptr = nullptr)
//             : _ptr(ptr)
//         {}

//         auto_ptr(auto_ptr<T>& ap)
//         {
//             _ptr = ap._ptr;
//             ap._ptr = nullptr;
//         }

//         auto_ptr<T>& operator=(auto_ptr<T>& ap)
//         {
//             if(_ptr != ap._ptr)
//             {
//                 if(_ptr)
//                     delete _ptr;

//                 _ptr = ap._ptr;
//                 ap._ptr = nullptr;
//             }
//             return *this;
//         }

//         ~auto_ptr()
//         {
//             if(_ptr)
//                delete _ptr;
//         }

//         T& operator*()
//         {
//             return *_ptr;
//         }

//         T* operator->()
//         {
//             return _ptr;
//         }

//     private:
//         T* _ptr;
//     };
// }
// int main()
// {
//     my::auto_ptr<int> ap1(new int(3));
//     //拷贝
//     my::auto_ptr<int> ap2(ap1);
//     my::auto_ptr<int> ap3;
//     ap3 = ap2;
//     return 0;
// }

// struct Date
// {
//     Date(int year = 2003, int month = 10, int day = 16)
//         : _year(year)
//         , _month(month)
//         , _day(day)
//     {}
//     int _year;
//     int _month;
//     int _day;
// };
// template <class T>
// class SmartPtr
// {
// public:
//     SmartPtr(T* ptr)
//         : _ptr(ptr)
//     {}
//     ~SmartPtr()
//     {
//         cout << "~SmartPtr()" << endl;
//         delete _ptr;
//     }
// private:
//     T* _ptr;
// };
// void Func()
// {
//     SmartPtr<int> sp(new int(3));
//     int x = 2, y = 0;
//     if(y == 0)
//         throw "除0错误";
//     else 
//         cout << "x / y = " << x / y << endl;
// }
// int main()
// {
//     try
//     {
//         Func();
//     }
//     catch(const char* err)
//     {
//         cout << "捕获异常成功:" << err << endl;
//     }
//     catch(...)
//     {
//         cout << "捕获未知异常" << endl;
//     }
    
//     return 0;
// }
// void Func()
// {
//     int* a = new int(3); // a 抛异常
//     int* b = new int(4); // b 抛异常
//     int* c = new int(5); // c 抛异常
//     //...一系列操作
//     delete a;
//     delete b;
//     delete c;
// }
// int main()
// {
//     try
//     {
//         Func();
//     }
//     catch(const exception& err)
//     {
//         cout << "捕获异常成功:" << err.what() << endl;
//     }
//     catch(...)
//     {
//         cout << "捕获未知异常" << endl;
//     }
    
//     return 0;
// }
// void Func()
// {
//     int* it = new int(3);
//     int x = 0, y = 0;
//     cin >> x >> y;
//     if(y == 0)
//         throw "除0错误";
//     else 
//         cout << x / y << endl;

//     cout << "delete success" << endl;
//     delete it;
// }
// int main()
// {
//     try
//     {
//         Func();
//     }
//     catch(const char* str)
//     {
//         cout << "捕获异常成功:" << str << endl;
//     }
//     catch(...)
//     {
//         cout << "捕获未知异常" << endl;
//     }
    
//     return 0;
// }
// template <typename T>
// class unique_ptr
// {
// public:

//     explicit unique_ptr(T* ptr = nullptr)
//         : _ptr(ptr)
//     {}

//     unique_ptr(const unique_ptr<T>& up) = delete; //unique_ptr，直接禁止拷贝和赋值
//     unique_ptr<T>& operator=(const unique_ptr<T>& up) = delete;

//     ~unique_ptr()
//     {
//         if(_ptr)
//         {
//             delete  _ptr;
//             _ptr = nullptr;
//         }
//     }

//     T& operator*()
//     {
//         return *_ptr;
//     }

//     T* operator->()
//     {
//         return _ptr;
//     }

// private:
//     T* _ptr;
// };
// int main()
// {
//     unique_ptr<int> uq1(new int(3));
//     unique_ptr<int> uq2(uq1);
//     unique_ptr<int> uq3(new int(1));
//     uq1 = uq3;
//     return 0;
// }
// template <typename T>
// class SmartPtr_Easy
// {
// public:

//     explicit SmartPtr_Easy(T* ptr = nullptr)
//         : _ptr(ptr)
//     {}

//     ~SmartPtr_Easy()
//     {
//         if(_ptr)
//         {
//             delete  _ptr;
//             _ptr = nullptr;
//         }
//     }

//     T& operator*()
//     {
//         return *_ptr;
//     }

//     T* operator->()
//     {
//         return _ptr;
//     }

// private:
//     T* _ptr;
// };
// struct Date
// {
//     Date(int year = 2024, int month = 4, int day = 21)
//         : _year(year)
//         , _month(month)
//         , _day(day)
//     {}

//     int _year;
//     int _month;
//     int _day;
// };
// int main()
// {
//     SmartPtr_Easy<Date> sp(new Date(2003, 10, 16));
//     cout << sp->_year << ":" << sp->_month << ":" << sp->_day << endl;
//     return 0;
// }
// template <class T>
// class SmartPtr
// {
// public:
//     explicit SmartPtr(T* ptr)
//         : _ptr(ptr)
//     {
//         cout << "explicit SmartPtr(T* ptr)" << endl;
//     }
//     ~SmartPtr()
//     {
//         cout << "~SmartPtr()" << endl;
//         delete[] _ptr;
//     }
// private:
//     T* _ptr;
// };
// void foo()
// {
//     int x, y;
//     SmartPtr<int> sp1(new int[10]);
//     cin >> x >> y;
//     if(y == 0)
//         throw "除0 error";
//     else 
//     {
//         cout << x / y << endl;
//     }
// }
// int main()
// {
//     try
//     {
//         foo();
//     }
//     catch(const char* errmsg)
//     {
//         cout << "捕获异常成功："<<  errmsg << endl;
//     }
//     catch(...)
//     {
//         cout << "捕获未知异常" << endl;
//     }
    
//     return 0;
// }
// int div()
// {
//     int a, b;
//     cin >> a >> b;
//     if (b == 0)
//         throw invalid_argument("除0错误");
//     return a / b;
// }
// void Func()
// {
//     // 1、如果p1这里new 抛异常会如何？
//     // 2、如果p2这里new 抛异常会如何？
//     // 3、如果div调用这里又会抛异常会如何？
//     int* p1 = new int;
//     int* p2 = new int;
//     cout << div() << endl;
//     delete p1;
//     delete p2;
// }
// int main()
// {
//     try
//     {
//         Func();
//     }
//     catch (exception& e)
//     {
//         cout << e.what() << endl;
//     }
//     return 0;
// }
// template <class T>
// struct _SmartPtr
// {
//     _SmartPtr(T* ptr)
//         : __ptr(ptr)
//     {
//         _count = 1;
//     }
//     _SmartPtr(const _SmartPtr<T>& s)
//     {
//         ++_count;
//         __ptr = s.__ptr;
//     }
//     ~_SmartPtr()
//     {
//         if(--_count == 0)
//         {
//             delete __ptr;
//             __ptr = nullptr;
//         }
//     }
//     T* __ptr;
//     static int _count;
// };
// template <class T>
// int _SmartPtr<T>::_count = 0;

// template <class T>
// class SmartPtr
// {
// public:
//     SmartPtr(T* ptr)
//         : _SmartPtr(ptr)
//     {}
//     SmartPtr(const SmartPtr<T>& s)
//         : _SmartPtr(s._ptr)
//     {}
//     ~SmartPtr()
//     {
//         _ptr.~_SmartPtr();
//     }
// private:
//     _SmartPtr<T> _ptr;
// };
// int main()
// {
//     SmartPtr<int> sm1(new int(1));
//     SmartPtr<int> sm2(sm1);
//     return 0;
// }
// class A 
// {
// public:
//     A()
//     {}
// };
// void foo()
// {
//     throw new A; 
// }
// int main()
// {
//     try
//     {
//         foo();
//     }
//     catch(A* a)
//     {
//         cout << "捕获成功" << endl;
//     }
//     catch(...)
//     {
//         cout << "捕获未知异常" << endl;
//     }
// }
#include "test.h"
int main()
{
    cout << a << endl;
    return 0;
}
//string modifyString(string s)
//{
//    for(int i = 0; i < s.size(); ++i)
//    {
//        if(s[i] == '?')
//        {
//            char a = '\0', b = '\0';
//            if(i - 1 > 0)
//            {
//                a = s[i - 1];
//            }
//            if(i + 1 < s.size())
//            {
//                b = s[i + 1];
//            }
//            for(char j = 'a'; j <= 'z'; ++j)
//            {
//                if(j != a && j != b)
//                {
//                    s[i] = j;
//                    break;
//                }
//            }
//        }
//    }
//    return s;
//}
//int main()
//{
//    string s = "??yw?ipkj?";
//    s = modifyString(s);
//    return 0;
//}
//#include <algorithm>
//#include <iostream>
//#include <string>
//using namespace std;
//
//string solve(string s, string t)
//{
//    string ret;
//    int i = s.size() - 1;
//    int j = t.size() - 1;
//    int tmp = 0; //进位
//    while(i >= 0 || j >= 0 || tmp)
//    {
//        if(i >= 0)
//            tmp += s[i--] - '0';
//        if(j >= 0)
//            tmp += t[j--] - '0';
//        ret += tmp % 10 + '0';
//        tmp /= 10;
//    }
//    reverse(ret.begin(), ret.end());
//    return ret;
//}
//
//int main()
//{
//    string s1, s2, ret;
//    cin >> s1 >> s2;
//
//    if(s1 == "0" || s2 == "0")
//    {
//        cout << "0" << endl;
//        return 0;
//    }
//
//    for(int i = s1.size() - 1; i >= 0; --i)
//    {
//        string sum; //记录每次*的结果
//        int tmp = 0; // 记录进位
//        for(int n = 0; n < s1.size() - 1 - i; ++n)
//            sum += '0';
//
//        for(int j = s2.size() - 1; j >= 0 || tmp; )
//        {
//            if(j >= 0)
//                tmp += (s1[i] - '0') * (s2[j--] - '0');
//            sum += tmp % 10 + '0';
//            tmp /= 10;
//        }
//        reverse(sum.begin(), sum.end()); //反向
//        ret = solve(ret, sum);
//    }
//    cout << ret << endl;
//    return 0;
//}
//#include <iostream>
//#include <vector>
//#include <string>
//using namespace std;
//int main()
//{
//    return 0;
//}
/**
 * #include <iostream>
#include <string>
using namespace std;
int main()
{
    //输入字符串
    string sin;
    cin >> sin;

    int begin = 0, end = 0, max_len = 0;
    string max;

    while(end < sin.size())
    {
        //不是数字
        while(end < sin.size() && !(sin[end] >= '0' && sin[end] <= '9'))
        {
            ++begin;
            ++end;
        }
        //是数字
        while(end < sin.size() && (sin[end] >= '0' && sin[end] <= '9'))
        {
            ++end;
        }

        if(max_len < (end - begin))
        {
            max = string(sin.begin() + begin, sin.begin() + end);
            max_len = end - begin;
        }

        begin = end;
    }

    cout << max << endl;
    return 0;
}
 */
////设计一个类，只能在栈上创建对象
//class StackRoom
//{
//public:
//    void* operator new(size_t n) = delete;
//    void operator delete(void* ) = delete;
//    StackRoom(int a = int())
//        : _a(a)
//    {}
//    StackRoom(const StackRoom& s)
//        :_a(s._a)
//    {}
//    StackRoom& operator=(const StackRoom& s)
//    {
//        if(this != &s)
//        {
//            _a = s._a;
//        }
//        return *this;
//    }
//private:
//    int _a;
//};
//int main()
//{
//    const int a = 3;
//    int* p = const_cast<int*> (&a);
//    cout << p <<  endl << &a << endl;
//    cout << *p << endl << a << endl;
//    *p = 4;
//    cout << p <<  endl << &a << endl;
//    cout << *p << endl << a << endl;
//    return 0;
//}
////设计一个类，只能在堆上创建对象
//template <class T>
//class HeapPlease
//{
//public:
//    static HeapPlease<T>* GetRoomHeap(const T& x)
//    {
//        return new HeapPlease(x);
//    }
//    static void Destory(HeapPlease<T>*& h)
//    {
//        delete h;
//        h = nullptr;
//    }
//
//    HeapPlease(const HeapPlease&) = delete;
//    HeapPlease& operator=(const HeapPlease&) = delete;
//private:
//    explicit HeapPlease(const T& x)
//        : _x(x)
//    {}
//    T _x;
//};
//int main()
//{
////    shared_ptr<HeapPlease<vector<int>>> sh (HeapPlease<vector<int>>::GetRoomHeap({1,2,3,4,5}), [](HeapPlease<vector<int>>* del){HeapPlease<vector<int>>::Destory(del);});
//    return 0;
//}
//class HeapPlease
//{
//public:
//    HeapPlease(int x = int(), char y = char())
//        : _x(new int(x))
//        , _y(new char(y))
//    {}
//    HeapPlease(const HeapPlease& h)
//        : _x(new int(*h._x))
//        , _y(new char(*h._y))
//    {}
//    HeapPlease& operator=(const HeapPlease& h)
//    {
//        if(this != &h)
//        {
//            delete _x;
//            delete _y;
//            _x = new int(*h._x);
//            _y = new char(*h._y);
//        }
//        return *this;
//    }
//    ~HeapPlease()
//    {
//        delete _x;
//        delete _y;
//        _x = nullptr;
//        _y = nullptr;
//    }
//private:
//    int* _x;
//    char* _y;
//};
//int main()
//{
//    HeapPlease h1(1,'a');
//    HeapPlease h2(h1);
//    HeapPlease h3;
//    h3 = h1;
//
//    return 0;
//}
//namespace my
//{
//    template <class T>
//    class shared_ptr
//    {
//    public:
//        template <class D>
//        shared_ptr(T* ptr, D del)
//                : _ptr(ptr)
//                , _count(new int(1))
//                , _del(del)
//        {}
//
//        shared_ptr(const shared_ptr<T>& sp)
//                : _ptr(sp._ptr)
//                , _count(sp._count)
//        {
//            ++(*_count);
//        }
//
//        shared_ptr<T>& operator=(const shared_ptr<T>& sp)
//        {
//            if(_ptr != sp._ptr)
//            {
//                //赋值， sp1 = sp2，因为赋值后，sp1就不再管理自己的资源了，所以要先释放
//                //但是此时也要通过引用计数，我们不能保证只有sp1管理这段资源
//                _release();
//                _ptr = sp._ptr;
//                _count = sp._count;
//                ++(*_count);
//            }
//            return *this;
//        }
//
//        ~shared_ptr()
//        {
//            cout << "~shared_ptr()" << endl;
//            _release();
//        }
//
//        int use_count()
//        {
//            return *_count;
//        }
//
//        T& operator*()
//        {
//            return *_ptr;
//        }
//
//        T* operator->()
//        {
//            return _ptr;
//        }
//
//    private:
//        T* _ptr;
//        int* _count;
//        function<void(T*)> _del = [](T* ptr){delete ptr;};
//
//
//        //////////////////////////////////////////////
//        void _release()
//        {
//            //当引用计数为0时，就可以释放资源
//            if(--(*_count) == 0)
//            {
//                _del(_ptr);
//                delete _count;
//                _ptr = nullptr;
//                _count = nullptr;
//            }
//        }
//    };
//}
//int main()
//{
////    my::shared_ptr<int> sp1(new int[10], [](int* ptr){delete[] ptr;});
//    my::shared_ptr<vector<int>> sp2(new vector<int>{1,2,3,4,5,6,7,8,9,0}, [](vector<int>* vptr){delete vptr;});
//    return 0;
//}
//#include <memory>
//#include <iostream>
//using namespace std;
//int main()
//{
//    unique_ptr<int> up1(new int(2));
//    unique_ptr<int> up2(up1);
//    unique_ptr<int> up3;
//    up3 = up1;
//    return 0;
//}
/*
template <class T>
class SmartPtr
{
public:
    SmartPtr(T* ptr)
            : _ptr(ptr)
    {}
    ~SmartPtr()
    {
        cout << "~SmartPtr()" << endl;
        delete _ptr;
    }
private:
    T* _ptr;
};
void Func()
{
    SmartPtr<int> sp(new int(3));*/
//    int x = 2, y = 0;
//    if(y == 0)
//        throw "除0错误";
//    else
//        cout << "x / y = " << x / y << endl;
//}
//int main()
//{
//    try
//    {
//        Func();
//    }
//    catch(const char* err)
//    {
//        cout << "捕获异常成功:" << err << endl;
//    }
//    catch(...)
//    {
//        cout << "捕获未知异常" << endl;
//    }
//
//    return 0;
//}
//#include <iostream>
//using namespace std;
//namespace wyd
//{
//    template <class T>
//    class shared_ptr
//    {
//    public:
//        explicit shared_ptr(T* ptr)
//            : _ptr(ptr)
//            , _count(new int(1))
//        {}
//        shared_ptr(const wyd::shared_ptr<T>& sp)
//        {
//            _ptr = sp._ptr;
//            _count = sp._count;
//            ++(*_count);
//        }
//        wyd::shared_ptr<T>& operator=(wyd::shared_ptr<T>& sp)
//        {
//            if(_ptr != sp._ptr)
//            {
//                release();
//                _ptr = sp._ptr;
//                _count = sp._count;
//                ++(*_count);
//            }
//            return *this;
//        }
//
//        ~shared_ptr()
//        {
//            release();
//        }
//
//        T& operator*()
//        {
//            return *_ptr;
//        }
//
//        T* operator->()
//        {
//            return _ptr;
//        }
//
//        T* get()
//        {
//            return _ptr;
//        }
//
//        int get_count()
//        {
//            return *_count;
//        }
//
//    private:
//        T* _ptr;
//        int* _count;
//        void release()
//        {
//            if(--(*_count) == 0)
//            {
//                delete _ptr;
//                delete _count;
//                _ptr = nullptr;
//                _count = nullptr;
//            }
//        }
//    };
//}
//int main()
//{
//    wyd::shared_ptr<int> sp(new int(10));
//    wyd::shared_ptr<int> sp2(sp);
//    wyd::shared_ptr<int> sp3(new int(2));
//    sp2 = sp3;
//
//    return 0;
//}
//namespace wyd
//{
//    template <typename T>
//class unique_ptr {
//public:
//
//    explicit unique_ptr(T *ptr = nullptr)
//            : _ptr(ptr) {}
//
//    unique_ptr(const unique_ptr<T> &up) = delete; //unique_ptr，直接禁止拷贝和赋值
//    unique_ptr<T> &operator=(const unique_ptr<T> &up) = delete;
//
//    ~unique_ptr() {
//        if (_ptr) {
//            delete _ptr;
//            _ptr = nullptr;
//        }
//    }
//
//    T &operator*() {
//        return *_ptr;
//    }
//
//    T *operator->() {
//        return _ptr;
//    }
//
//private:
//    T *_ptr;
//};
//
//}
//int main()
//{
//    unique_ptr<int> uq1(new int(3));
//    unique_ptr<int> uq2(uq1);
//    unique_ptr<int> uq3(new int(1));
//    uq1 = uq3;
//    return 0;
//}
//#include <iostream>
//using namespace std;
//template <typename T>
//class SmartPtr_Easy
//{
//public:
//
//    explicit SmartPtr_Easy(T* ptr = nullptr)
//            : _ptr(ptr)
//    {}
//
//    ~SmartPtr_Easy()
//    {
//        if(_ptr)
//        {
//            delete  _ptr;
//            _ptr = nullptr;
//        }
//    }
//
//    T& operator*()
//    {
//        return *_ptr;
//    }
//
//    T* operator->()
//    {
//        return _ptr;
//    }
//
//private:
//    T* _ptr;
//};
//struct Date
//{
//    Date(int year = 2024, int month = 4, int day = 21)
//            : _year(year)
//            , _month(month)
//            , _day(day)
//    {}
//
//    int _year;
//    int _month;
//    int _day;
//};
//int main()
//{
//    SmartPtr_Easy<Date> sp(new Date(2003, 10, 16));
//    cout << sp->_year << ":" << sp->_month << ":" << sp->_day << endl;
//    return 0;
//}
//#include <iostream>
//using namespace std;
//
//template <class T>
//class SmartPtr
//{
//public:
//    SmartPtr(T* ptr)
//            : _ptr(ptr)
//            , _count(new int(1))
//    {}
//
//    SmartPtr(const SmartPtr<T>& s)
//    {
//        _ptr = s._ptr;
//        _count = s._count;
//        ++(*_count);
//    }
//    SmartPtr<T>& operator=(const SmartPtr<T>& s)
//    {
//        if(s._ptr == _ptr) //防止自己给自己赋值，这里用_ptr，是因为可能存在多个指向_ptr的对象
//            return *this;
//
//        release();
//
//        _ptr = s._ptr;
//        _count = s._count;
//        ++(*_count);
//
//        return *this;
//    }
//    ~SmartPtr()
//    {
//        release();
//    }
//    void release()
//    {
//        if(--(*_count) == 0)
//        {
//            delete _ptr;
//            delete _count;
//            _ptr = nullptr;
//            _count = nullptr;
//        }
//    }
//    int use_count()
//    {
//        return *_count;
//    }
//
//    T& operator*()
//    {
//        return *_ptr;
//    }
//
//    T* operator->()
//    {
//        return _ptr;
//    }
//
//private:
//    T* _ptr;
//    int* _count;
//};
//
//int main()
//{
//    SmartPtr<int> sm1(new int(1));
//
//    SmartPtr<int> sm2(sm1);
//
//    SmartPtr<int> sm3(new int(3));
//    sm3 = sm1;
//    return 0;
//}
//#include <iostream>
//#include <vector>
//using namespace std;
//class A
//{
//public:
//    A()
//    {
//        cout << "hh" << endl;
//    }
//};
//int main()
//{
//    A a;
//    return 0;
//}
//void CheckZero_One(vector<vector<int>>& grid, int line_size, int column_size,
//                   int& count_one, int& count_zero)
//{
//    for(int i = 0; i < line_size; ++i)
//    {
//        for(int j = 0; j < column_size; ++j)
//        {
//            if(grid[i][j] == 0)
//                ++count_zero;
//            if(grid[i][j] == 1)
//                ++count_one;
//        }
//    }
//}
//
//bool check(vector<vector<int>>& grid, int i, int j, int line_size, int column_size)
//{
//    //判断上下左右是否为0，不为0，则继续，为0就返回-1
//    if((i + 1 < line_size) && (grid[i + 1][j] != 0))
//        return false;
//    if((j - 1 >= 0) && (grid[i][j - 1] != 0 ))
//        return false;
//    if((j + 1 < column_size) && (grid[i][j + 1] != 0))
//        return false;
//    if((i - 1 >= 0) && (grid[i - 1][j] != 0))
//        return false;
//    return true;
//}
//bool check_two_zero(vector<vector<int>>& grid, int i, int j, int line_size, int column_size)
//{
//    if((i + 1 < line_size) && (grid[i + 1][j] != 0))
//        return false;
//    if((j - 1 >= 0) && (grid[i][j - 1] != 0 ))
//        return false;
//    if((j + 1 < column_size) && (grid[i][j + 1] != 0))
//        return false;
//    if((i - 1 >= 0) && (grid[i - 1][j] != 0))
//        return false;
//    return true;
//}
//void spread(vector<vector<int>>& grid, int i, int j,
//            int line_size, int column_size, int flag, int& count_one)
//{
//    //这里先不腐烂，等遍历一次后再统一腐烂，所以设置为3，防止干扰
//    if(i + 1 < line_size)
//        grid[i + 1][j] == 1 ? grid[i + 1][j] = 3 , --count_one : flag;
//    if(j - 1 >= 0)
//        grid[i][j - 1] == 1 ? grid[i][j - 1] = 3 , --count_one : flag;
//    if(j + 1 < column_size)
//        grid[i][j + 1] == 1 ? grid[i][j + 1] = 3 , --count_one : flag;
//    if(i - 1 >= 0)
//        grid[i - 1][j] == 1 ? grid[i - 1][j] = 3 , --count_one : flag;
//}
//
//int rotApple(vector<vector<int> >& grid) {
//    int t = 0; //时间：min
//    int line_size = grid.size(); //行
//    int column_size = grid[0].size(); //列
//    int flag = 1; //没啥用，就是为了补条件表达式的最后一个条件语句的
//
//    int count_one = 0; //计算1的个数
//    int count_zero = 0;//计算0的个数
//
//    CheckZero_One(grid, line_size, column_size, count_one, count_zero);
//    //只有1和0
//    if (count_one + count_zero == line_size * column_size && count_one != 0)
//        return -1;
//    //只有2和0/只有2/只有0
//    if (count_one == 0)
//        return 0;
//
//    //有0，1，2
//    while (count_one) //结束条件1 ：没有完好的苹果了
//    {
//        for (int i = 0; i < line_size; ++i) //遍历行
//        {
//            for (int j = 0; j < column_size; ++j) //遍历列
//            {
//                //记录完整苹果，并判断是否永远不会腐烂
//                if (grid[i][j] == 1) {
//                    if (check(grid, i, j, line_size, column_size)) //判断苹果四周是否为0
//                        return -1; //结束条件2:存在不会腐烂的苹果
//                }
//
//                //更新上一轮腐烂的苹果
//                if (grid[i][j] == 3)
//                    grid[i][j] = 2;
//
//                //找到腐烂的苹果
//                if (grid[i][j] == 2) {
//                    //判断2周围是否为0，为0则阻断传播
//                    if (check_two_zero(grid, i, j, line_size, column_size)) {
//                        grid[i][j] = 0;
//                        ++count_zero;
//
//                        if (count_one + count_zero == line_size * column_size
//                            && count_one != 0)
//                            return -1; //存在不会腐烂的苹果
//                    } else
//                        spread(grid, i, j, line_size, column_size, flag, count_one); //腐烂传播
//                }
//            }
//        }
//        ++t;
//    }
//    return t;
//}
//int LastRemaining_Solution(int n, int m)
//{
//    //使用位图，先初始化
//    vector<size_t> arr;
//    arr.resize(n / 32 + 1, 0);
//
//    int num = n / 32; //对应几个完整的元素
//    int pos_size = n % 32; //对应不完整的元素：对应几个比特位
//    if(num)
//    {
//        for(int i = 0; i < num; ++i)
//            arr[i] = 0xffffffff;
//    }
//    arr[num] |= ((1 << pos_size) - 1);
//    //至此位图基本构建完成，映射关系构建完成
//
//    int p = 0; //每次都从p开始移动
//    int size_n = n; //看剩余几个小朋友
//    int move = (m - 1) % n; //每次移动多少距离，超过的部分就再走一圈
//
//    while(size_n > 1)
//    {
//        for(int i = 0; i < move;)
//        {
//            if((arr[p/32] & (1 << (p%32))) != 0) //当前有小朋友，没有出列
//                ++i;
//            ++p;
//            p %= n;
//        }
//        while((arr[p/32] & (1 << (p%32))) == 0)
//        {
//            ++p;
//            p %= n;
//        }
//        arr[p/32] &= ~(1 << p);
//        --size_n;
//    }
//
//    for(int i = 0; i < arr.size(); ++i)
//    {
//        if(arr[i] != 0)
//        {
//            for(int j = 0; j < 32; ++j)
//            {
//                if(arr[i] & (1 << j))
//                {
//                    return i * 32 + j - 1;
//                }
//            }
//        }
//    }
//    return -1;
//}
//int main()
//{
//    LastRemaining_Solution(10,17);
//    return 0;
//}
//#include "myvector.h"
//void Fun(int &x){ cout << "左值引用" << endl; }
//void Fun(const int &x){ cout << "const 左值引用" << endl; }
//void Fun(int &&x){ cout << "右值引用" << endl; }
//void Fun(const int &&x){ cout << "const 右值引用" << endl; }
//template<typename T>
//void PerfectForward(T&& t)
//{
//    Fun(t);
//}
//int main()
//{
//    PerfectForward(10); // 右值
//    int a;
//    PerfectForward(a); // 左值
//    PerfectForward(std::move(a)); // 右值
//    const int b = 8;
//    PerfectForward(b); // const 左值
//    PerfectForward(std::move(b)); // const 右值
//    return 0;
//}
//MY::string&& func()
//{
//    MY::string str = "hello world";
//    return str;
//}
//void Test()
//{
//    MY::string str = func();
//}
//传引用，不需要拷贝
//void func1(vector<vector<int>>& darr)
//{
//    //.....
//}
////传值，需要拷贝
//void func2(vector<vector<int>> darr)
//{
//    //.....
//}
//
//vector<int>& func3(vector<int>& arr)
//{
//    //....
//    return arr; //这里的返回值就是出函数作用域还存在，可以用引用返回，减少拷贝
//}
//
//vector<int> func4(vector<int>& arr)
//{
//    //....
//    return arr; //这里就是多了个拷贝
//}
//
////两者对比，对于出作用域还存在的返回值，可以使用左值引用返回
//
//void Func1(vector<string> v_str)
//{
//    //...
//}
//
////这里必须是返回值严格出函数作用域不销毁，才可以使用左值引用返回
//vector<string>& Func3(vector<string>& L_str)
//{
//    //...
//    return L_str;
//}
//
//vector<string> Func2(vector<string>& L_str)
//{
//    //...
//    return L_str;
//}


//int main()
//{
//    vector<string> v_str = {"Hello", "CSDN"};
//
//    Func1(v_str);
//    Func1({"hello", "C++"});
//
//    Func2(v_str);
//    Func2({"hello", "C++"});

//    return 0;
//}
// 左边 = 右边
//    int a = 3;           //a为左值，3为右值
//
//    int& ar1 = a;        //左值引用 可以引用 左值
//
//    int&& ar2 = a;       //右值引用 不可以引用 左值
//    int&& ar3 = move(a); //右值引用可以 引用move后的左值
//    int&& ar4 = a;       //但是a本身的性质不变，依旧是左值
//
//    int& ar5 = 3;        //左值引用 不可以引用 右值
//    const int& ar6 = 3;  //const 左值引用 可以引用 右值
//
//    int&& ar7 = 3;       // 右值引用 可以引用 右值
//
//
//    int b = a;           //左值 可以   放在 ‘=’ 的右边
//    3 = a;               //右值 不可以 放在 ‘=’ 的左边


//c = 5;
//    b = c;

//    const int x = 10;
//   // x = 12; //虽然x不可出现在 ‘ = ’的左边
//   // const int&& y = x;   //右值引用无法引用
//    const int& z = x;    //左值引用可以引用，但必须是const，要保证权限
////                         从语法上证明，x仍为左值
//    int arr[] = {1,2,3,4,5};
//    const int a = 0;
//    int b = 8;
//    b = a;
//    const int&& c = a;
//    const int& d = a;
//
//    return 0;
//}// #include <iostream>
// #include <vector>
// #include <string>
// #include <cassert>
// using namespace std;
// //设计一个类，不能被继承
// class A final
// {
// public:
// private:
// };
//设计一个类，只有单例对象（只可以实例化一次）
//若类只有单例对象，那只允许创建一次，不允许拷贝和赋值
//饿汉模式
// class OneClass
// {
// public:
//     static GetInit()
//     {
//         return &oneclass;
//     }
//     //禁用赋值和拷贝
//     OneClass(const OneClass& oneclass) = delete;
//     OneClass& operator=(const OneClass& oneclass) = delete;
// private:
//     OneClass(){}
//     static OneClass oneclass; //这里使用静态成员变量，类型为OneClass，静态成员变量在main函数之前初始化。
// };                            //但是会导致，在main函数之前若要创造多个单例对象，会使其进入main函数缓慢
//                               //main函数之后才会有多线程
// OneClass OneClass::oneclass;
// //为了解决这一问题，出现了懒汉模式
// class Lazy
// {
// public:
    
//     Lazy(const Lazy& l) = delete;
//     Lazy& operator=(const Lazy& l) = delete;
// private:
//     Lazy(){}
//     static Lazy* pl;    
// };
// Lazy* Lazy::pl = nullptr;
// class OneClass
// {
// public:
//     OneClass()
//     {
//         assert(flag == 0);
//         ++flag;
//     }
//     //禁用赋值和拷贝
//     OneClass(const OneClass& oneclass) = delete;
//     OneClass& operator=(const OneClass& oneclass) = delete;
// private:
//     static int flag;
// };
// int OneClass::flag = 0;
// int main()
// {
//     // int a = 6;

//     // double b = static_cast<double>(a);
//     // double d = a;

//     // char c = static_cast<char>(97);
//     int a = 12;
//     int b = 200;
//     cout <<  b % a << endl;
//     // cout << a << endl;
//     // cout << b << endl;
//     // cout << d << endl;
//     // cout << c << endl;
//     return 0;
// }
// {
//     vector<int> a = {1,2,3,4,5};
//     vector<double> b = {1.1, 4.5, 3.6, 2.3, 4.1};
//     b = a;
//     return 0;
// }//#include <iostream>
//#include <vector>
//using namespace std;
//int _ReversePairs(vector<int>& record, int left, int right)
//{
//    if(left >= right)
//        return 0;
//
//    int mid = (left + right) / 2;
//    int ret_left = 0, ret_right = 0;
//    ret_left =  _ReversePairs(record, left, mid);
//    ret_right = _ReversePairs(record, mid + 1, right);
//
//    int cur1 = left; //遍历左边排序好的数组
//    int cur2 = mid + 1; //遍历右边排序好的数组
//    vector<int> temp(right - left + 1, 0); //临时数组，用于放置将归并排序好的数组
//    int i = 0; //temp的下标计数
//    int count = 0; //该侧的逆序对个数
//    while(cur1 <= mid && cur2 <= right)
//    {
//        //说明cur1所指元素对逆序对没有贡献
//        if(record[cur1] <= record[cur2])
//        {
//            temp[i++] = record[cur1++];
//        }
//        else
//        {
//            temp[i++] = record[cur2++];
//            count += mid - cur1 + 1; //[cur1, mid]的值对逆序对都有贡献
//        }
//    }
//    //剩下没放入temp的元素，放入temp
//    while(cur1 <= mid || cur2 <= right)
//    {
//        if(cur1 <= mid)
//        {
//            temp[i++] = record[cur1++];
//        }
//        if(cur2 <= right)
//        {
//            temp[i++] = record[cur2++];
//        }
//    }
//    //copy回到record
//    for(int n = left; n <= right; ++n)
//    {
//        record[n] = temp[n - left];
//    }
//
//    return count + ret_right + ret_left;
//}
//int ReversePairs(vector<int>& record)
//{
//    return _ReversePairs(record, 0, record.size() - 1);
//}
//int main()
//{
//    //数组大小
//    int size = 0;
//    while(cin >> size)
//    {
//        //输入数组元素
//        cout << "请输入数组元素" << endl;
//        vector<int> A(size, 0);
//        for(auto& e : A)
//        {
//            cin >> e;
//        }
//        cout << "逆序对数：";
//        cout <<  ReversePairs(A) << endl;
//    }
//    return 0;
//}
//    const int a = 8;
//    const int*  b = &a;
//    const int*& d = b;
//    int* c = const_cast<int*>(d);
//    const int a =8;
//    int* b = const_cast<int*>(&a);
//    const char c = 'a';
//    const char* pc = &c;
//    char* pc2 = const_cast<char*>(pc);
//    *pc2 = 'b';
//    int d = 9;
//    int* const a = &d;
//    int* b = static_cast<int*>(a);
//    *b = 4;
//    int b = 3;
//    void* p = &b;
//    int* pb = reinterpret_cast<int*>(p);
//    cout << *pb << endl;
//    int a = 6;
//    double b = 12.34;
//    double c = static_cast<double>(a);
//    cout << c << endl;
//    double d = 1;
//    cout << d << endl;
//    cout << a << endl << b << endl;// #include <iostream>
// #include <vector>
// using namespace std;
// int _ReversePairs(vector<int>& record, int left, int right)
// {
//     if(left >= right)
//         return 0;

//     int mid = (left + right) / 2;
//     int ret_left = 0, ret_right = 0;
//     ret_left =  _ReversePairs(record, left, mid); //记录左侧的逆序对个数
//     ret_right = _ReversePairs(record, mid + 1, right); //记录右侧的逆序对个数
    
//     int cur1 = left; //遍历左边排序好的数组
//     int cur2 = mid + 1; //遍历右边排序好的数组
//     vector<int> temp(right - left + 1, 0); //临时数组，用于放置将归并排序好的数组
//     int i = 0; //temp的下标计数
//     int count = 0; //该侧的逆序对个数
//     while(cur1 <= mid && cur2 <= right)
//     {
//         //说明cur1所指元素对逆序对没有贡献
//         if(record[cur1] <= record[cur2])
//         {
//             temp[i++] = record[cur1++];
//         }
//         else
//         {
//             temp[i++] = record[cur2++];
//             count += mid - cur1 + 1; //[cur1, mid]的值对逆序对都有贡献
//         }
//     }
//     //剩下没放入temp的元素，放入temp
//     while(cur1 <= mid || cur2 <= right)
//     {
//         if(cur1 <= mid)
//         {
//             temp[i++] = record[cur1++];
//         }
//         if(cur2 <= right)
//         {
//             temp[i++] = record[cur2++];
//         }
//     }
//     //copy回到record
//     for(int n = left; n <= right; ++n)
//     {
//         record[n] = temp[n - left];
//     }

//     return count + ret_right + ret_left; //返回当前逆序对个数+左右侧的
    
// }
// int ReversePairs(vector<int>& record)
// {
//     return _ReversePairs(record, 0, record.size() - 1);
// }
// int main()
// {
//     //数组大小
//     int size = 0;
//     cin >> size;
//     //输入数组元素
//     vector<int> A(size, 0);
//     for(auto& e : A)
//     {
//         cin >> e;
//     }
//     cout <<  ReversePairs(A) << endl;
//     return 0;
// }
#include <vector>
#include <string>
#include <iostream>
using namespace std;
int numDecodings(string s) 
{
    if(s[0] == '0')
        return 0;

    int n = s.size();
    vector<int> dp(n + 1);
    dp[1] = 1;
    for(int i = 2; i < n + 1; ++i)
    {
        int flag = 0;

        string str(s.begin() + i - 2, s.begin() + i - 1);
        if(str[1] == '0' && (str[0] > '2' || str[0] == '0'))
        {
            return 0;
        }
        else if(str[0] == '0')
        {
            flag = 0;
        }
        else if((atoi(str.c_str()) <= 26) && (str[1] != '0'))
        {
            flag = 1;
        }
        else if((atoi(str.c_str()) <= 26) && (str[1] == '0'))
        {
            flag = 0;
        }


        dp[i] = dp[i - 1] + flag;
    }
    return dp[n];
}
int main()
{
    int ret = numDecodings("10");
    cout << ret << endl;
    return 0;
}// #include <iostream>
// #include <vector>
// using namespace std;
// int _ReversePairs(vector<int>& record, int left, int right)
// {
//     if(left >= right)
//         return 0;

//     int mid = (left + right) / 2;
//     int ret_left = 0, ret_right = 0;
//     ret_left =  _ReversePairs(record, left, mid); //记录左侧的逆序对个数
//     ret_right = _ReversePairs(record, mid + 1, right); //记录右侧的逆序对个数
    
//     int cur1 = left; //遍历左边排序好的数组
//     int cur2 = mid + 1; //遍历右边排序好的数组
//     vector<int> temp(right - left + 1, 0); //临时数组，用于放置将归并排序好的数组
//     int i = 0; //temp的下标计数
//     int count = 0; //该侧的逆序对个数
//     while(cur1 <= mid && cur2 <= right)
//     {
//         //说明cur1所指元素对逆序对没有贡献
//         if(record[cur1] <= record[cur2])
//         {
//             temp[i++] = record[cur1++];
//         }
//         else
//         {
//             temp[i++] = record[cur2++];
//             count += mid - cur1 + 1; //[cur1, mid]的值对逆序对都有贡献
//         }
//     }
//     //剩下没放入temp的元素，放入temp
//     while(cur1 <= mid || cur2 <= right)
//     {
//         if(cur1 <= mid)
//         {
//             temp[i++] = record[cur1++];
//         }
//         if(cur2 <= right)
//         {
//             temp[i++] = record[cur2++];
//         }
//     }
//     //copy回到record
//     for(int n = left; n <= right; ++n)
//     {
//         record[n] = temp[n - left];
//     }

//     return count + ret_right + ret_left; //返回当前逆序对个数+左右侧的
    
// }
// int ReversePairs(vector<int>& record)
// {
//     return _ReversePairs(record, 0, record.size() - 1);
// }
// int main()
// {
//     //数组大小
//     int size = 0;
//     cin >> size;
//     //输入数组元素
//     vector<int> A(size, 0);
//     for(auto& e : A)
//     {
//         cin >> e;
//     }
//     cout <<  ReversePairs(A) << endl;
//     return 0;
// }
// #include <vector>
// #include <string>
// #include <iostream>
// using namespace std;
// int numDecodings(string s) 
// {
//     if(s[0] == '0')
//         return 0;

//     int n = s.size();
//     vector<int> dp(n + 1);
//     dp[1] = 1;
//     for(int i = 2; i < n + 1; ++i)
//     {
//         int flag = 0;

//         string str(s.begin() + i - 2, s.begin() + i - 1);
//         if(str[1] == '0' && (str[0] > '2' || str[0] == '0'))
//         {
//             return 0;
//         }
//         else if(str[0] == '0')
//         {
//             flag = 0;
//         }
//         else if((atoi(str.c_str()) <= 26) && (str[1] != '0'))
//         {
//             flag = 1;
//         }
//         else if((atoi(str.c_str()) <= 26) && (str[1] == '0'))
//         {
//             flag = 0;
//         }


//         dp[i] = dp[i - 1] + flag;
//     }
//     return dp[n];
// }
// int main()
// {
//     int ret = numDecodings("10");
//     cout << ret << endl;
//     return 0;
// }
// class Solution 
// {
// public:
//     int numDecodings(string s) 
//     {
//         int n = s.size();
        
//         //前导0，返回0
//         if(s[0] == '0')   return 0;

//         //无前导0
//         vector<int> dp(n + 1);
//         dp[0] = 1;
//         dp[1] = 1;
//         for(int i = 2; i <= n; ++i)
//         {
//             //临时字符串，存以i为长度的s的最高两位字符
//             string str(s.begin() + i - 2, s.begin() + i);
            
//             if(str[1] == '0')
//             {
//                 //10
//                 if(str[0] <= '2' && str[0] > '0')
//                 {
//                     if(i - 3 >= 0)
//                     {
//                         //210
//                         if(s[i - 3] <= '2')   dp[i] = dp[i - 2];
//                         //810  
//                         else   dp[i] = dp[i - 1];
//                     }
//                     else   dp[i] = dp[i - 1];
//                 }
//                 //80 / 00
//                 else if(str[0] > '2' || str[0] == '0')   return 0;
//             }
//             else 
//             {
//                 //12
//                 if(atoi(str.c_str()) <= 26 && str[0] != '0')   dp[i] = dp[i - 1] + dp[i - 2];
//                 //32 / 01
//                 else   dp[i] = dp[i - 1];
//             }
//         }
//         return dp[n];
//     }
// };
#include <iostream>
int main()

{
    return 0;
}//#include <iostream>
////#include <string>
////#include <vector>
////#include <list>
////#include <queue>
////#include <deque>
////#include <stack>
////#include <map>
////#include <set>
//#include <cassert>
//using namespace std;
////创建一棵树，必须要先创建树的节点
////创建AVL树的节点
////节点应该包括 指向左右子树的指针；节点存储的值；节点的平衡因子；节点指向父亲节点的指针
////而我们在找到树的节点时，应该可以随意去访问树的左右指针，父指针和内部的元素，所以这里需定义节点为public，struct类默认权限为public
//template <class T>
//struct AVLTreeNode
//{
//    AVLTreeNode(const T& val)
//        : _left(nullptr)
//        , _right(nullptr)
//        , _parent(nullptr)
//        , _bf(0)
//        , _val(val)
//    {}
//    typedef AVLTreeNode<T> Node;
//    Node* _left;
//    Node* _right;
//    Node* _parent;
//    int _bf; /// balance factor
//    T _val;
//};
//
////定义好树的节点，就可以开始定义树，树这里我们就不希望访问树的成员变量，而希望使用成员函数，所以我们设定为class类
//template <class T>
//class AVLTree
//{
//public:
//    typedef AVLTreeNode<T> Node;
//    AVLTree()
//        : _root(nullptr)
//    {}
//
//    //计算高度
//    int Height()
//    {
//        return _Height(_root);
//    }
//
//    //AVL树的验证
//    //要验证一个AVL树，我们就不应该根据bf来判定，因为这是一个毫无疑义的验证方法
//    //当你的bf值记录更新错误，我们还是按照错误的方式来验证的，验证就永远为AVL树
//    //所以我们要根据其左右子树的高度去计算
//    bool AssertAVLTree()
//    {
//        int height = 0;
//        return _AssertAVLTree(_root, height);
//    }
//
//    //中序遍历
//    void InOrder()
//    {
//        _InOrder(_root);
//        cout << endl;
//    }
//
//    //AVL树的插入，要满足二叉搜索树的性质，左孩子小于根，右孩子大于根
//    bool insert(const T& val)
//    {
//        if(_root == nullptr) //空树
//        {
//            _root = new Node(val);
//            if(_root == nullptr)
//                assert(false);
//        }
//        else //不为空树
//        {
//            Node* cur = _root;
//            Node* parent = _root;
//
//            //根据二叉搜索树性质判断插入的位置
//            while(cur)
//            {
//                if(cur->_val < val)
//                {
//                    parent = cur;
//                    cur = cur->_right;
//                }
//                else if(cur->_val > val)
//                {
//                    parent = cur;
//                    cur = cur->_left;
//                }
//                else
//                {
//                    return false;
//                }
//            }
//
//            //插入新节点
//            Node* newnode = new Node(val);
//            if(parent->_val > val)
//            {
//                parent->_left = newnode;
//            }
//            else
//            {
//                parent->_right = newnode;
//            }
//            newnode->_parent = parent;
//
//            //更新平衡因子
//            while(parent)
//            {
//                if(parent->_left == newnode)
//                {
//                    --parent->_bf;
//                }
//                else
//                {
//                    ++parent->_bf;
//                }
//
//                if (parent->_bf == 0)
//                {
//                    break;
//                }
//                else if (parent->_bf == 1 || parent->_bf == -1)
//                {
//                    newnode = parent;
//                    parent = parent->_parent;
//                }
//                else if (parent->_bf == 2 || parent->_bf == -2)
//                {
//                    //旋转
//                    if(parent->_bf == -2 && newnode->_bf == -1)
//                    {
//                        //右单旋
//                        RotationR(parent);
//                    }
//                    else if(parent->_bf == -2 && newnode->_bf == 1)
//                    {
//                       //先左后右
//                        RotationLR(parent);
//                    }
//                    else if(parent->_bf == 2 && newnode->_bf == 1)
//                    {
//                        //左单旋
//                        RotationL(parent);
//                    }
//                    else if(parent->_bf == 2 && newnode->_bf == -1)
//                    {
//                        RotationRL(parent);
//                    }
//                    else;
//
//                    break;
//                }
//                else;
//            }
//
//        }
//        return true;
//    }
//private:
//    Node* _root;
//    void _InOrder(Node* root)
//    {
//        if(root == nullptr)
//            return;
//        _InOrder(root->_left);
//        cout << root->_val << " ";
//        _InOrder(root->_right);
//    }
//    void RotationRL(Node* parent)
//    {
//        Node* pR = parent->_right;
//        Node* pRL = pR->_left;
//        int bf = pRL->_bf;
//
//        //先右单旋
//        RotationR(pR);
//        //后左单旋
//        RotationL(parent);
//
//        if(bf == 1)
//        {
//            pR->_bf = 0;
//            parent->_bf = -1;
//            pRL->_bf = 0;
//        }
//        else if(bf == -1)
//        {
//            pR->_bf = 1;
//            parent->_bf = 0;
//            pRL->_bf = 0;
//        }
//        else
//        {
//            pR->_bf = 0;
//            parent->_bf = 0;
//            pRL->_bf = 0;
//        }
//
//    }
//    void RotationLR(Node* parent)
//    {
//        Node* pL = parent->_left;
//        Node* pLR = pL->_right;
//        int bf = pLR->_bf;
//
//        //先左单旋
//        RotationL(pL);
//        //后右单旋
//        RotationR(parent);
//
//        if(bf == 1)
//        {
//            pL->_bf = -1;
//            parent->_bf = 0;
//            pLR->_bf = 0;
//        }
//        else if(bf == -1)
//        {
//            pL->_bf = 0;
//            parent->_bf = 1;
//            pLR->_bf = 0;
//        }
//        else
//        {
//            pL->_bf = 0;
//            parent->_bf = 0;
//            pLR->_bf = 0;
//        }
//    }
//    void RotationL(Node* parent)
//    {
//        Node* pR = parent->_right;
//        Node* pRL = pR->_left;
//
//        parent->_right = pRL;
//        if(pRL)
//            pRL->_parent = parent;
//        pR->_left = parent;
//        Node* ppnode = parent->_parent;
//        parent->_parent = pR;
//
//        if(parent == _root)
//        {
//            _root = pR;
//            pR->_parent = nullptr;
//        }
//        else
//        {
//            if(ppnode->_left == parent)
//                ppnode->_left = pR;
//            else
//                ppnode->_right = pR;
//            pR->_parent = ppnode;
//        }
//
//        parent->_bf = 0;
//        pR->_bf = 0;
//    }
//    void RotationR(Node* parent)
//    {
//        Node* pL = parent->_left;
//        Node* pLR = pL->_right;
//
//        parent->_left = pLR;
//        if(pLR)
//            pLR->_parent = parent;
//        pL->_right = parent;
//        Node* ppnode = parent->_parent;
//        parent->_parent = pL;
//
//        if(_root == parent)
//        {
//            _root = pL;
//            pL->_parent = nullptr;
//        }
//        else
//        {
//            if(ppnode->_left == parent)
//                ppnode->_left = pL;
//            else
//                ppnode->_right = pL;
//            pL->_parent = ppnode;
//        }
//
//        pL->_bf = 0;
//        parent->_bf = 0;
//    }
//
//
//
//    bool _AssertAVLTree(Node* root, int& height)
//    {
//
//        if(root == nullptr)
//        {
//            height = 0;
//            return true;
//        }
//
//        //计算左子树高度
//        int leftH = 0;
//        //计算右子树高度
//        int rightH = 0;
//        if(!_AssertAVLTree(root->_left, leftH)
//        || !_AssertAVLTree(root->_right, rightH))
//            return false;
//
//
//        if(abs(leftH - rightH) >= 2)
//        {
//            cout << "树高度差超过2" << endl;
//            return false;
//        }
//        else if(rightH - leftH != root->_bf)
//        {
//            cout << "平衡因子数据异常" << endl;
//            return false;
//        }
//
//        height = leftH > rightH ? leftH + 1 : rightH + 1;
//        return true;
//    }
//    int _Height(Node* root)
//    {
//        if(root == nullptr)
//            return 0;
//
//        int left_height = _Height(root->_left);
//        int right_height = _Height(root->_right);
//
//        return left_height > right_height ? left_height + 1 : right_height + 1;
//    }
//};
#pragma once
#include <iostream>
#include<assert.h>
#include<vector>

template<class K, class V>
struct AVLTreeNode
{
    AVLTreeNode<K, V>* _left;
    AVLTreeNode<K, V>* _right;
    AVLTreeNode<K, V>* _parent;
    int _bf; // balance factor
    pair<K, V> _kv;

    AVLTreeNode(const pair<K, V>& kv)
            :_left(nullptr)
            , _right(nullptr)
            , _parent(nullptr)
            , _bf(0)
            , _kv(kv)
    {}
};

template<class K, class V>
class AVLTree
{
    typedef AVLTreeNode<K, V> Node;
public:
    bool Insert(const pair<K, V>& kv)
    {
        if (_root == nullptr)
        {
            _root = new Node(kv);
            return true;
        }

        Node* parent = nullptr;
        Node* cur = _root;
        while (cur)
        {
            if (cur->_kv.first < kv.first)
            {
                parent = cur;
                cur = cur->_right;
            }
            else if (cur->_kv.first > kv.first)
            {
                parent = cur;
                cur = cur->_left;
            }
            else
            {
                return false;
            }
        }

        cur = new Node(kv);
        if (parent->_kv.first < kv.first)
        {
            parent->_right = cur;
        }
        else
        {
            parent->_left = cur;
        }
        cur->_parent = parent;

        while (parent)
        {
            if(cur == parent->_left)
            {
                parent->_bf--;
            }
            else
            {
                parent->_bf++;
            }

            if (parent->_bf == 0)
            {
                break;
            }
            else if (parent->_bf == 1 || parent->_bf == -1)
            {
                cur = cur->_parent;
                parent = parent->_parent;
            }
            else if (parent->_bf == 2 || parent->_bf == -2)
            {
                // 旋转处理
                if (parent->_bf == 2 && cur->_bf == 1)
                {
                    RotateL(parent);
                }
                else if (parent->_bf == -2 && cur->_bf == -1)
                {
                    RotateR(parent);
                }
                else if (parent->_bf == -2 && cur->_bf == 1)
                {
                    RotateLR(parent);
                }
                else
                {
                    RotateRL(parent);
                }

                break;
            }
            else
            {
                // 插入之前AVL树就有问题
                assert(false);
            }
        }

        return true;
    }

    void RotateL(Node* parent)
    {
        Node* subR = parent->_right;
        Node* subRL = subR->_left;

        parent->_right = subRL;
        if(subRL)
            subRL->_parent = parent;

        subR->_left = parent;
        Node* ppnode = parent->_parent;
        parent->_parent = subR;

        if (parent == _root)
        {
            _root = subR;
            subR->_parent = nullptr;
        }
        else
        {
            if (ppnode->_left == parent)
            {
                ppnode->_left = subR;
            }
            else
            {
                ppnode->_right = subR;
            }
            subR->_parent = ppnode;
        }

        parent->_bf = 0;
        subR->_bf = 0;
    }

    void RotateR(Node* parent)
    {
        Node* subL = parent->_left;
        Node* subLR = subL->_right;

        parent->_left = subLR;
        if (subLR)
            subLR->_parent = parent;

        subL->_right = parent;

        Node* ppnode = parent->_parent;
        parent->_parent = subL;

        if (parent == _root)
        {
            _root = subL;
            subL->_parent = nullptr;
        }
        else
        {
            if (ppnode->_left == parent)
            {
                ppnode->_left = subL;
            }
            else
            {
                ppnode->_right = subL;
            }
            subL->_parent = ppnode;
        }

        subL->_bf = 0;
        parent->_bf = 0;
    }

    void RotateLR(Node* parent)
    {
        Node* subL = parent->_left;
        Node* subLR = subL->_right;

        int bf = subLR->_bf;
        RotateL(parent->_left);
        RotateR(parent);

        if (bf == -1)
        {
            subLR->_bf = 0;
            subL->_bf = 0;
            parent->_bf = 1;
        }
        else if (bf == 1)
        {
            subLR->_bf = 0;
            subL->_bf = -1;
            parent->_bf = 0;
        }
        else if (bf == 0)
        {
            subLR->_bf = 0;
            subL->_bf = 0;
            parent->_bf = 0;
        }
        else
        {
            assert(false);
        }
    }

    void RotateRL(Node* parent)
    {
        Node* subR = parent->_right;
        Node* subRL = subR->_left;
        int bf = subRL->_bf;

        RotateR(subR);
        RotateL(parent);

        subRL->_bf = 0;
        if (bf == 1)
        {
            subR->_bf = 0;
            parent->_bf = -1;
        }
        else if (bf == -1)
        {
            parent->_bf = 0;
            subR->_bf = 1;
        }
        else
        {
            parent->_bf = 0;
            subR->_bf = 0;
        }
    }

    void _InOrder(Node* root)
    {
        if (root == nullptr)
            return;

        _InOrder(root->_left);
        cout << root->_kv.first << "[" << root->_bf << "]" << endl;
        _InOrder(root->_right);
    }

    void InOrder()
    {
        _InOrder(_root);
    }

    int _Height(Node* root)
    {
        if (root == nullptr)
            return 0;

        int leftHeight = _Height(root->_left);
        int rightHeight = _Height(root->_right);

        return leftHeight > rightHeight ? leftHeight + 1 : rightHeight + 1;
    }

    int Height()
    {
        return _Height(_root);
    }

    bool _IsBalance(Node* root, int& height)
    {
        if (root == nullptr)
        {
            height = 0;
            return true;
        }

        int leftHeight = 0, rightHeight = 0;
        if (!_IsBalance(root->_left, leftHeight)
            || !_IsBalance(root->_right, rightHeight))
        {
            return false;
        }

        if (abs(rightHeight - leftHeight) >= 2)
        {
            cout <<root->_kv.first<<"不平衡" << endl;
            return false;
        }

        if (rightHeight - leftHeight != root->_bf)
        {
            cout << root->_kv.first <<"平衡因子异常" << endl;
            return false;
        }

        height = leftHeight > rightHeight ? leftHeight + 1 : rightHeight + 1;

        return true;
    }

    bool IsBalance()
    {
        int height = 0;
        return _IsBalance(_root, height);
    }

    size_t Size()
    {
        return _Size(_root);
    }

    size_t _Size(Node* root)
    {
        if (root == NULL)
            return 0;

        return _Size(root->_left)
               + _Size(root->_right) + 1;
    }

    Node* Find(const K& key)
    {
        Node* cur = _root;
        while (cur)
        {
            if (cur->_kv.first < key)
            {
                cur = cur->_right;
            }
            else if (cur->_kv.first > key)
            {
                cur = cur->_left;
            }
            else
            {
                return cur;
            }
        }

        return NULL;
    }
private:
    Node* _root = nullptr;
};




























#include "bitset.h"
//布隆过滤器是为了解决非整型的数据的海量搜索问题
class Hashfunc1
{
public:
    size_t operator()(const string& s)
    {
        size_t hash = 0;
        for (auto ch : s)
        {
            hash *= 131;
            hash += ch;
        }

        return hash;
    }
};
class Hashfunc2
{
public:
    size_t operator()(const string& s)
    {
        size_t hash = 0;
        for (size_t i = 0; i < s.size(); i++)
        {
            if ((i & 1) == 0) // 偶数位字符
            {
                hash ^= ((hash << 7) ^ (s[i]) ^ (hash >> 3));
            }
            else              // 奇数位字符
            {
                hash ^= (~((hash << 11) ^ (s[i]) ^ (hash >> 5)));
            }
        }

        return hash;
    }
};
class Hashfunc3
{
public:
    size_t operator()(const string& s)
    {
        size_t hash = 5381;
        for (auto ch : s)
        {
            hash = hash * 33 ^ ch;
        }

        return hash;
    }
};
template <size_t N, class T = string,
          class Hashfunc1 = Hashfunc1,
          class Hashfunc2 = Hashfunc2,
          class Hashfunc3 = Hashfunc3>


class BHB
{
public:

    void set(const T& val)
    {
        _bs.test(Hashfunc1()(val) % M);
        _bs.test(Hashfunc2()(val) % M);
        _bs.test(Hashfunc3()(val) % M);
    }

    bool test(const T& val)
    {
        if(_bs.test(Hashfunc1()(val) % M)
        && _bs.test(Hashfunc2()(val) % M)
        && _bs.test(Hashfunc3()(val)) % M)
            return true;
        return false;
    }
private:
    static const size_t M = N * 4;
    wyd::bitset<M> _bs;
};#include <iostream>
#include <cassert>
using namespace std;
//思考：创建一个二叉搜索树，首先要构造树的节点，其次再实现树的结构
//创建树的节点时，必须思考节点内部应该包含哪些变量？
// 1. 节点代表的值，2. 节点指向左右子树的指针，3. 指向父亲节点的指针
//开始构建树的节点，我们希望节点内部的成员可以被外界使用，所以使用struct类
template <class V>
struct BSTreeNode
{
    BSTreeNode(const V& val)
        : _val(val)
        , _left(nullptr)
        , _right(nullptr)
        , _parent(nullptr)
    {}
    V _val;
    BSTreeNode<V>* _left;
    BSTreeNode<V>* _right;
    BSTreeNode<V>* _parent;
};
template <class V>
class Comp
{
public:
    bool operator()(const V& v1, const V& v2)
    {
        return v1 < v2;
    }
};
template<>
class Comp<string>
{
public:
    bool operator()(const string& s1, const string& s2)
    {
        return s1 > s2;
    }
};

//构造完节点，下一步去设计树的结构，我们希望二叉搜索树只对外界展现成员函数，所以使用class类
template <class V, class Comp = Comp<V>>
class BSTree
{
public:
    typedef BSTreeNode<V> Node;

    //插入
    bool insert(const V& val)
    {
        //空树
        if(_root == nullptr)
        {
            _root = new Node(val);
            return true;
        }
        //非空树
        else
        {
            Comp comp;
            Node* cur = _root;
            Node* parent = nullptr;
            while(cur)
            {
                if(comp(val, cur->_val))
                {
                    parent = cur;
                    cur = cur->_left;
                }
                else if(comp(cur->_val, val))
                {
                    parent = cur;
                    cur = cur->_right;
                }
                else
                {
                    cout << "不允许插入已有的数据" << endl;
                    return false;
                }
            }

            //已经找到插入节点的父亲节点，开始判断插入左边还是右边
            Node* newnode = new Node(val);

            // 比根小，去左边插入
            if(comp(val, parent->_val))
            {
                parent->_left = newnode;
            }
            // 比根大，去右边插入
            else
            {
                parent->_right = newnode;
            }
            newnode->_parent = parent;
            return true;
        }
    }
    //删除
    bool erase(const V& val)
    {
        //没有节点了
        assert(size() > 0);

        Node* del_node = find(val);

        //1. 被删除节点不存在
        if(del_node == nullptr)
            return false;

        //2. 被删除节点只有左孩子/只有右孩子/左右孩子都没有
        else if(del_node->_left == nullptr || del_node->_right == nullptr)
        {
            //删除节点为根结点
            if(del_node == _root)
            {
                _root = del_node->_left == nullptr ? del_node->_right : del_node->_left;
                delete del_node;
                return true;
            }

            //不为根结点
            Node* parent = del_node->_parent;
            //只有左孩子
            if(del_node->_left != nullptr)
            {
                if(parent->_left == del_node)
                {
                    parent->_left = del_node->_left;
                }
                else
                {
                    parent->_right = del_node->_left;
                }
                del_node->_left->_parent = parent;
            }
            //只有右孩子
            else if(del_node->_right != nullptr)
            {
                if(parent->_left == del_node)
                {
                    parent->_left = del_node->_right;
                }
                else
                {
                    parent->_right = del_node->_right;
                }
                del_node->_right->_parent = parent;
            }
            //为叶节点，要处理叶节点的父亲节点被删除的孩子置为空
            else
            {
                parent->_left == del_node ?
                parent->_left = nullptr:
                parent->_right = nullptr;
            }
            delete del_node;
            del_node = nullptr;
        }
        //3. 被删除节点有左右孩子
        else
        {
            //这里只实现找左子树的最右节点，另外的方法大家自行实现
            Node* find_LT_right = del_node->_left;
            while(find_LT_right->_right)
            {
                find_LT_right = find_LT_right->_right;
            }
            //交换值
            swap(find_LT_right->_val, del_node->_val);
            //删除叶节点

            //删除之前，要让其父节点的被删除孩子指向空
            //这里不是父节点的右孩子原因：左子树只有一个节点
            find_LT_right == find_LT_right->_parent->_left ?
            find_LT_right->_parent->_left = nullptr
            : find_LT_right->_parent->_right = nullptr;

            delete find_LT_right;
            find_LT_right = nullptr;
        }
        return true;
    }
    //查找
    Node* find(const V& val)
    {
        Comp comp;
        Node* cur = _root;
        while(cur)
        {
            if(comp(val, cur->_val))
            {
                cur = cur->_left;
            }
            else if(comp(cur->_val, val))
            {
                cur = cur->_right;
            }
            else
            {
                return cur;
            }
        }
        return nullptr;
    }
    //中序遍历 -》 有序
    void inorder()
    {
        _inorder(_root);
        cout << endl;
    }
    //节点个数
    size_t size()
    {
        return _size(_root);
    }
    //求高度
    size_t height()
    {
        return _height(_root);
    }
private:
    Node* _root = nullptr; //这里使用指针的原因是动态的增删查改
    void _inorder(Node* root)
    {
        if(root == nullptr)
            return;
        _inorder(root->_left);
        cout << root->_val << " ";
        _inorder(root->_right);
    }
    size_t _size(Node* root)
    {
        if(root == nullptr)
            return 0;

        return _size(root->_left) + _size(root->_right) + 1;
    }
    size_t _height(Node* root)
    {
        if(root == nullptr)
            return 0;

        //求左子树的高度
        size_t left = _height(root->_left);
        //求右子树的高度
        size_t right = _height(root->_right);

        //返回左右子树最大的高度，作为树的高度
        return left > right ? left + 1 : right + 1;
    }
};cmake_minimum_required(VERSION 3.26)
project(CLion)

set(CMAKE_CXX_STANDARD 11)

add_executable(
        CLion main.cpp
        AVLTree.h
        RBTree.h
        NewRBTree.h
        myset.h
        mymap.h
        newmap.h
        newset.h
        work_rbtree.h
        NewAVLTree.h
        HashTable.h
        my_unorder_Set.h
        my_unorder_Map.h
        bitset.h
        BHB.h
        BinarySearchTree.h
        betterBSTree.h
        myvector.h
        file.h)
#pragma once
#include <iostream>
#include <vector>
#include <cstring>
using namespace std;
//////////////////////////////////////////////////////////////
template <class T>
class Comp
{
public:
    bool operator()(const T& val1, const T& val2)
    {
        return val1 == val2;
    }
};

template<>
class Comp<string>
{
public:
    bool operator()(const string& s1, const string& s2)
    {
        return strcmp(s1.c_str(), s2.c_str()) == 0;
    }
};
////////////////////////////////////////////////////////////
template<class T>
class GetInt
{
public:
    size_t operator()(const T& val)
    {
        return (size_t)val;
    }
};

template<>
class GetInt<string>
{
public:
    size_t operator()(const string& s)
    {
        size_t ret = 0;
        for(auto& e : s)
        {
            ret += e;
            ret *= 131;
        }
        return ret;
    }
};
////////////////////////////////////////////////////////////
template <class T>
struct HashListNode
{
    explicit HashListNode(const T& val)
            : _val(val)
            , _next(nullptr)
    {}

    T _val;
    HashListNode<T>* _next;
};
////////////////////////////////////////////////////////////

template <class K, class T, class TOfK, class GetInt>
struct Hash_Iterator
{
    typedef HashListNode<T> Node;
    typedef Hash_Iterator<K, T, TOfK, GetInt> Self;

    Hash_Iterator(Node* node, vector<Node*>* v)
            : _hash_node(node)
            , _v(v)
    {}

    T& operator*()
    {
        return _hash_node->_val;
    }


    T* operator->()
    {
        return &_hash_node->_val;
    }

    Self& operator++()
    {
        if(_hash_node->_next)
        {
            _hash_node = _hash_node->_next;
        }
        else
        {
            TOfK t_of_k;
            GetInt get_int;
            int hash_pos = get_int(t_of_k(_hash_node->_val)) % _v->size();
            ++hash_pos;

            while(hash_pos < _v->size())
            {
                if((*_v)[hash_pos] != nullptr)
                {
                    _hash_node = (*_v)[hash_pos];
                    break;
                }
                ++hash_pos;
            }
            if(hash_pos == _v->size())
                _hash_node = nullptr;
        }
        return *this;
    }
    Self operator++(int)
    {
        Self copy = *this;
        ++(*this);
        return copy;
    }

    bool operator!=(Self another)
    {
        return _hash_node != another._hash_node;
    }

    bool operator==(Self another)
    {
        return _hash_node == another._hash_node;
    }

    Node* _hash_node;
    vector<Node*>* _v;
};

////////////////////////////////////////////////////////////
template <class K, class T, class TOfK, class GetInt, class Comp = Comp<K>>
class HashList
{
public:

    typedef HashListNode<T> Node;
    typedef Hash_Iterator<K, T, TOfK, GetInt> iterator;


    iterator begin()
    {
        for(auto e : _hs)
        {
            if(e != nullptr)
            {
                return iterator(e, &_hs);
            }
        }
        return end();
    }

    iterator end()
    {
        return iterator(nullptr, &_hs);
    }

    HashList()
    {
        _hs.resize(10, nullptr);
    }
    explicit HashList(const size_t size)
    {
        _hs.resize(size, nullptr);
    }
    ~HashList()
    {
        for(auto e : _hs)
        {
            Node* cur = e;
            while(cur)
            {
                e = cur->_next;
                delete cur;
                cur = e;
            }
        }
    }
    size_t size()
    {
        return _n;
    }
    bool empty()
    {
        return _n == 0;
    }
    pair<iterator, bool> insert(const T& val)
    {
        TOfK t_of_k;
        GetInt get_i;

        iterator node = find(val);
        if(node._hash_node)
            return pair<iterator, bool>(node, false);

        if(_n == _hs.size())
        {
            HashList<K, T, TOfK, GetInt> new_hs(_hs.size() * 2);
            for(auto& e : _hs)
            {
                Node *cur = e;
                while (cur)
                {
                    size_t new_pos = get_i(t_of_k(cur->_val)) % new_hs._hs.size();
                    e = cur->_next;
                    cur->_next = new_hs._hs[new_pos];
                    new_hs._hs[new_pos] = cur;
                    cur = e;
                }
            }
            _hs.swap(new_hs._hs);

        }

        size_t hash_pos =  get_i(t_of_k(val)) % _hs.size();
        Node* newnode = new Node(val);
        newnode->_next = _hs[hash_pos];
        _hs[hash_pos] = newnode;
        ++_n;
        return pair<iterator, bool>(iterator(newnode, &_hs), true);
    }

    iterator find(const T& val)
    {
        TOfK t_of_k;
        GetInt get_i;
        Comp compare;
        size_t hash_pos =  get_i(t_of_k(val)) % _hs.size();
        Node* cur = _hs[hash_pos];
        while(cur)
        {
            if(compare(t_of_k(cur->_val), t_of_k(val)))
            {
                return iterator(cur, &_hs);
            }
            cur = cur->_next;
        }
        return iterator(cur, &_hs);
    }

    iterator erase(const T& val)
    {
        TOfK t_of_k;
        GetInt get_i;
        Comp compare;
        size_t hash_pos =  get_i(t_of_k(val)) % _hs.size();
        Node* cur = _hs[hash_pos];
        Node* prev = _hs[hash_pos];
        while(cur)
        {
            if(compare(t_of_k(cur->_val), t_of_k(val)))
            {
                if(cur == _hs[hash_pos])
                    _hs[hash_pos] = cur->_next;
                else
                    prev->_next = cur->_next;

                delete cur;
                --_n;
                return iterator(prev->next, &_hs);
            }
            prev = cur;
            cur = cur->_next;
        }
        return iterator(nullptr, &_hs);
    }
private:
    vector<Node*> _hs;
    size_t _n = 0;

};


//
//namespace OpenHash
//{
//    template<class T>
//    class HashFunc
//    {
//    public:
//        size_t operator()(const T& val)
//        {
//            return val;
//        }
//    };
//
//    template<>
//    class HashFunc<string>
//    {
//    public:
//        size_t operator()(const string& s)
//        {
//            const char* str = s.c_str();
//            unsigned int seed = 131; // 31 131 1313 13131 131313
//            unsigned int hash = 0;
//            while (*str)
//            {
//                hash = hash * seed + (*str++);
//            }
//
//            return hash;
//        }
//    };
//
//    template<class V>
//    struct HashBucketNode
//    {
//        HashBucketNode(const V& data)
//                : _pNext(nullptr), _data(data)
//        {}
//        HashBucketNode<V>* _pNext;
//        V _data;
//    };
//
//    // 本文所实现的哈希桶中key是唯一的
//    template<class V, class HF = HashFunc<V>>
//
//    class HashBucket
//    {
//        typedef HashBucketNode<V> Node;
//        typedef Node* PNode;
//
//        typedef HashBucket<V, HF> Self;
//
//    public:
//        HashBucket()
//                : _table(10, nullptr)
//                , _size(0)
//        {}
//
//        ~HashBucket()
//        {
//            Clear();
//        }
//
//        // 哈希桶中的元素不能重复
//        bool Insert(const V& data)
//        {
//            if(Find(data))
//                return false;
//
//            if(_size == _table.size()) //负载因子达到1了，需要扩容
//            {
//                HF hf;
//                vector<Node*> _new_table(_table.size() * 2, nullptr);
//                for(auto& e : _table)
//                {
//                    if(e)
//                    {
//                        Node* cur = e;
//                        while(cur)
//                        {
//                            size_t pos = hf(cur->_data) % _new_table.size();
//                            e = cur->_pNext;
//                            cur->_pNext = _new_table[pos];
//                            _new_table[pos] = cur;
//                            cur = e;
//                        }
//                    }
//                }
//                _table.swap(_new_table);
//            }
//
//            HF hf;
//            Node* newnode = new Node(data);
//            size_t pos = hf(data) % _table.size();
//            newnode->_pNext = _table[pos];
//            _table[pos] = newnode;
//            ++_size;
//            return true;
//        }
//
//        // 删除哈希桶中为data的元素(data不会重复)
//        bool Erase(const V& data)
//        {
//            if(!Find(data))
//                return false;
//
//            HF hf;
//            int pos = hf(data) % _table.size();
//            Node* cur = _table[pos];
//            Node* prev = nullptr;
//            while(cur)
//            {
//                if(cur->_data == data)
//                {
//                    if(cur == _table[pos])
//                    {
//                        _table[pos] = cur->_pNext;
//
//                    }
//                    else
//                    {
//                        prev->_pNext = cur->_pNext;
//                    }
//                    delete cur;
//                    break;
//                }
//                prev = cur;
//                cur = cur->_pNext;
//            }
//            --_size;
//            return true;
//        }
//
//        Node* Find(const V& data)
//        {
//            HF hf;
//            int pos = hf(data) % _table.size();
//            Node* cur = _table[pos];
//
//            while(cur)
//            {
//                if(cur->_data == data)
//                    return cur;
//                cur = cur->_pNext;
//            }
//
//            return nullptr;
//        }
//
//        size_t Size()const
//        {
//            return _size;
//        }
//
//        bool Empty()const
//        {
//            return 0 == _size;
//        }
//
//        void Clear()
//        {
//            for(auto e : _table)
//            {
//                if(e)
//                {
//                    Node* cur = e;
//                    while(cur)
//                    {
//                        e = cur->_pNext;
//                        delete cur;
//                        cur = e;
//                    }
//                }
//            }
//        }
//
//        size_t BucketCount()const
//        {
//            return _table.capacity();
//        }
//
//        void Swap(Self& ht)
//        {
//            _table.swap(ht._table);
//            swap(_size, ht._size);
//        }
//
//    private:
//        size_t HashFunc(const V& data)
//        {
//            return HF()(data) % _table.capacity();
//        }
//
//        void CheckCapacity();
//
//    private:
//        vector<Node*> _table;
//        size_t _size;      // 哈希表中有效元素的个数
//    };
//}
//
//#include <iostream>
//#include <vector>
//using namespace std;
////我们设计一个哈希结构，必须要清楚什么是哈希
////哈希是一种映射的结构，值与位置的映射
////而哈希表的底层为vector
//enum status //存储节点的状态
//{
//    Empty,
//    Exist,
//    Delete
//};
//
//template <class K>
//struct HashNode
//{
//    K _data;
//    status _sta = Empty;
//};
//
////仿函数
//template <class K>
//class Getint
//{
//public:
//    size_t operator()(const K& data)
//    {
//        return (size_t)data;
//    }
//};
////特化，特别实例化
//template<>
//class Getint<string>
//{
//public:
//    size_t operator()(const string& str)
//    {
//        int ascii = 0;
//        for(auto&e : str)
//        {
//            ascii += e;
//            ascii *= 131;
//        }
//        return ascii;
//    }
//};
//template <class K, class Getint = Getint<K>>
//class HashTable
//{
//public:
//    typedef HashNode<K> Node;
//    HashTable()
//    {
//        _kt.resize(10);
//    }
//
//    HashTable(const int& size)
//    {
//        _kt.resize(size);
//    }
//
//
//    bool erase(const K& data)
//    {
//        HashNode<K>* ret = find(data);
//        if(ret)
//        {
//            --_n;
//            ret->_sta = Delete;
//            return true;
//        }
//        return false;
//    }
//
//    bool insert(const K& data)
//    {
//        //拒绝重复值
//        if(find(data))
//            return false;
//
//        if((double)_n / (double)_kt.size() >= 0.7)
//        {
//            HashTable<K, Getint> new_kt(2 * _kt.size());
//
//            for(auto& e : _kt)
//            {
//                if(e._sta == Exist)
//                {
//                    new_kt.insert(e._data);
//                }
//            }
//            _kt.swap(new_kt._kt);
//        }
//
//        Getint getint;
//        int hash_pos = getint(data) % _kt.size();
//        while(_kt[hash_pos]._sta == Exist)
//        {
//            ++hash_pos;
//            hash_pos %= _kt.size();
//        }
//        _kt[hash_pos]._data = data;
//        _kt[hash_pos]._sta = Exist;
//        ++_n;
//        return true;
//    }
//
//    HashNode<K>* find(const K& data)
//    {
//        Getint getint;
//        int hash_pos = getint(data) % _kt.size();
//        while(_kt[hash_pos]._sta != Empty)
//        {
//            if(_kt[hash_pos]._sta == Exist && _kt[hash_pos]._data == data)
//                return &_kt[hash_pos];
//
//            ++hash_pos;
//            hash_pos %= _kt.size();
//        }
//        return nullptr;
//    }
//private:
//    vector<Node> _kt;
//    size_t _n = 0; //记录哈希表中的有效数据个数
//};#include <iostream>
#include <cassert>
using namespace std;
//////////////////////////////////
//我们在创造AVL树之前，先要把AVL树节点创造出来，要明确的是在AVLTreeNode类外
//我们还是需要使用到节点里面的内容，所以这里定义为struct类，默认权限为public
template <class T>
struct AVLTreeNode
{
    AVLTreeNode(const T& data)
        : _left(nullptr)
        , _right(nullptr)
        , _parent(nullptr)
        , _bf(0)
        , _data(data)
    {}
    AVLTreeNode<T>* _left;
    AVLTreeNode<T>* _right;
    AVLTreeNode<T>* _parent;
    int _bf;    //用_bf来记录树节点的左右子树高度差
    T _data;
};
///////////////////////////////////////
//创造完AVLTreeNode后，可以开始创造AVLTree
//需要注意的是，我们在日常使用AVL树时，只需要使用其成员函数，并不需要用成员变量
//所以设定为class类，成员函数权限为public，成员函数权限为private

template <class K, class Comp>
class AVLTree
{
public:
    //成员函数
    //插入函数
    bool insert(const K& data)
    {
        //这里插入规则与二叉搜索树一致
        //空树
        if(_root == nullptr)
        {
            _root = new Node(data);
            //创建失败
            if(_root == nullptr)
            {
                perror("new error");
                return false;
            }
            return true;
        }
        //不为空树
        else
        {
            Node* cur = _root;  //遍历找到插入的位置
            Node* parent = _root; //记录插入位置的父亲节点位置
            while(cur)
            {
                if(comp(cur->_data) > comp(data))  //插入值小于节点值：去左子树插入
                {
                    parent = cur;
                    cur = cur->_left;
                }
                else if(comp(cur->_data) < comp(data)) //插入值大于节点值：去右子树插入
                {
                    parent = cur;
                    cur = cur->_right;
                }
                else //插入值等于节点值：插入失败
                {
                    perror("insert a same data");
                    return false;
                }
            }

            //找到插入位置了，创造新节点
            Node* newnode = new Node(data);

            if(comp(parent->_data) > comp(data)) //新节点的值比父亲的值小，插入父亲的左侧
            {
                parent->_left = newnode;
            }
            else                     //新节点的值比父亲的值大，插入父亲的右侧
            {
                parent->_right = newnode;
            }
            newnode->_parent = parent;

            //更新平衡因子bf
            UpdateBF(newnode, parent);
            return true;
        }
    }

    //遍历
    void InOrder()
    {
        _InOrder(_root);
    }

    //判断是否为AVL树
    bool IsBalance()
    {
        int height = 0;
        return _IsBalance(_root, height);
    }
private:
    typedef AVLTreeNode<K> Node;
    Node* _root = nullptr;
    //以下成员函数不希望被外部看到，所以设为private

    //判断是否是AVL树
    bool _IsBalance(Node* root, int& height)
    {
        if (root == nullptr)
        {
            height = 0;
            return true;
        }

        int leftHeight = 0, rightHeight = 0;
        if (!_IsBalance(root->_left, leftHeight)
            || !_IsBalance(root->_right, rightHeight))
        {
            return false;
        }

        if (abs(rightHeight - leftHeight) >= 2)
        {
            cout <<root->_data<<"不平衡" << endl;
            return false;
        }

        if (rightHeight - leftHeight != root->_bf)
        {
            cout << root->_data <<"平衡因子异常" << endl;
            return false;
        }

        height = leftHeight > rightHeight ? leftHeight + 1 : rightHeight + 1;

        return true;
    }

    //遍历
    void _InOrder(Node* root)
    {
        if (root == nullptr)
            return;

        _InOrder(root->_left);
        cout << comp(root->_data)  << " ";
        _InOrder(root->_right);
    }

    //左旋转
    void RotationL(Node* parent, Node* cur)
    {
       Node* cleft = cur->_left;
       parent->_right = cleft;

       //cleft不为空，则需要链接其父亲，为空，则不用链接
       if(cleft)
           cleft->_parent = parent;

       cur->_left = parent;
       //
       Node* pparent = parent->_parent;
       parent->_parent = cur;

       if(parent == _root) //当parent就是根，旋转之后，cur就为根
       {
           _root = cur;
           cur->_parent = nullptr;
       }
       else //如果parent不是根，则需要判断parent在其父亲的左节点还是右节点
       {
           if(pparent->_left == parent)
           {
               pparent->_left = cur;
           }
           else
           {
               pparent->_right = cur;
           }
           cur->_parent = pparent;
       }

        //旋转之后，parent和cur的平衡因子都为0，不影响上层节点
        parent->_bf = 0;
        cur->_bf = 0;
    }

    //右旋转
    void RotationR(Node* parent, Node* cur)
    {
        Node* cright = cur->_right;
        parent->_left = cright;

        //cright存在，则链接其父亲到parent，不存在，不链接
        if(cright)
            cright->_parent = parent;

        cur->_right = parent;
        Node* pparent = parent->_parent;
        parent->_parent = cur;

        if(parent == _root) //当parent就是根，旋转之后，cur就为根
        {
            _root = cur;
            cur->_parent = nullptr;
        }
        else //如果parent不是根，则需要判断parent在其父亲的左节点还是右节点
        {
            if(pparent->_left == parent)
            {
                pparent->_left = cur;
            }
            else
            {
                pparent->_right = cur;
            }
            cur->_parent = pparent;
        }

        //旋转之后，parent和cur的平衡因子都为0，不影响上层节点
        parent->_bf = 0;
        cur->_bf = 0;
    }

    //左右旋转
    void RotationLR(Node* parent, Node* cur)
    {
        Node* cright = cur->_right;
        int bf = cright->_bf;

        RotationL(cur, cright);
        RotationR(parent, cright);

        if(bf == 1)
        {
            parent->_bf = 0;
            cright->_bf = 0;
            cur->_bf = -1;
        }
        else if(bf == -1)
        {
            parent->_bf = 1;
            cur->_bf = 0;
            cright->_bf = 0;
        }
        else
        {
            parent->_bf = 0;
            cur->_bf = 0;
            cright->_bf = 0;
        }
    }

    //右左旋转
    void RotationRL(Node* parent, Node* cur)
    {
        Node* cleft = cur->_left;
        int bf = cleft->_bf;

        RotationR(cur, cleft);
        RotationL(parent, cleft);

        if(bf == 1)
        {
            parent->_bf = -1;
            cleft->_bf = 0;
            cur->_bf = 0;
        }
        else if(bf == -1)
        {
            parent->_bf = 0;
            cur->_bf = 1;
            cleft->_bf = 0;
        }
        else
        {
            parent->_bf = 0;
            cur->_bf = 0;
            cleft->_bf = 0;
        }
    }

    //更新平衡因子
    void UpdateBF(Node*& cur, Node*& parent)
    {
        while(parent)
        {
            //我们在插入之前，parent的平衡因子可能为三种情况
            // 1、0、-1
            if(parent->_left == cur) //插入的节点在父亲的左边，bf--
            {
                --parent->_bf;
            }
            else //插入的节点在父亲的右边，bf++
            {
                ++parent->_bf;
            }

            //更新完平衡因子之后，parent的bf值可能为：2，1，0，-1，-2

            if(parent->_bf == 0)
            //说明parent在插入之前的bf为1或-1，以parent为根的左右子树高度差1
            //新增节点之后，也并不会影响整颗树的bf，只会让以parent为根的左右子树高度差更新为0
            {
                break;
            }
            else if(parent->_bf == -1 || parent->_bf == 1)
            //说明parent在插入之前的bf == 0，是AVL树，但是插入之后，会影响整体的高度
            //所以要依次向上更新
            {
                cur = parent;
                parent = cur->_parent;
            }
            else if(parent->_bf == 2 || parent->_bf == -2)
            //parent的平衡因子超过1，破坏了AVL树的规则，需要进行旋转
            //但是有4种旋转的情况
            {
                //情况1：左旋转
                if(parent->_bf == 2 && cur->_bf == 1)
                {
                    RotationL(parent, cur);
                }
                //情况2：右左旋转
                else if(parent->_bf == 2 && cur->_bf == -1)
                {
                    RotationRL(parent, cur);
                }
                //情况3：右旋转
                else if(parent->_bf == -2 && cur->_bf == -1)
                {
                    RotationR(parent, cur);
                }
                //情况4：左右旋转
                else if(parent->_bf == -2 && cur->_bf == 1)
                {
                    RotationLR(parent, cur);
                }
                else;

                //旋转结束、不需要更新
                break;
            }
            else
            {
                //平衡因子有问题
                assert(false);
            }

        }
    }
};
template <class K>
class AVL
{
public:
    class Comp
    {
    public:
        K& operator()(const K& data)
        {
            return data;
        }
        K& operator()(const pair<const K, V>& kv)
        {
            return kv.first;
        }
    };
private:
    AVLTree<K, Comp> avl_tree;
};














//实现红黑树，首先要确定红黑树的节点，其次再实现树结构
#include <iostream>
#include <cassert>
#include <stack>
using namespace std;
//红黑树的节点应该包含
//1. 存放的值；2.指向左右子树的指针 3.存放节点颜色 4. 指向父亲的指针
//红黑树节点的实现，必须为public，我们需要在红黑树类中使用RBTreeNode的成员变量
//////////////////////////////////////////////////
////////////////////RBTreeNode////////////////////
enum Color
{
    red,
    black
};
template <class V>
struct RBTreeNode
{
    RBTreeNode(const V& data)
        : _data(data)
        , _left(nullptr)
        , _right(nullptr)
        , _parent(nullptr)
        , _color(red)     ///插入的新节点默认是红色节点，保证每条路径的黑色节点数目相同
    {}

    V _data;
    RBTreeNode<V>* _left;
    RBTreeNode<V>* _right;
    RBTreeNode<V>* _parent;
    Color _color;
};
///////////////////////////////////////////////////
template <class V>
class RBTree_Iterator
{
public:
    typedef RBTreeNode<V> Node;
    typedef RBTree_Iterator<V> Self;

    RBTree_Iterator(Node* node)
        : _node(node)
    {}
    
    //内置类型
    V& operator*()
    {
        return _node->_data;   
    }
    
    //自定义类型
    V* operator->()
    {
        return &_node->_data;
    }
    
    bool operator==(const Self& it)
    {
        return _node == it._node;
    }

    bool operator!=(const Self& it)
    {
        return _node != it._node;
    }

    //前置++
    Self& operator++()
    {
        if(_node == nullptr)
        {
            cout << "错误" << endl;
            assert(false);
            return *this;
        }
        //右子树不为空，下一个元素为右子树的最左节点
        if(_node->_right)
        {
            _node = _node->_right;
            while(_node->_left)
            {
                _node = _node->_left;
            }
            return *this;
        }
        //右子树为空
        else
        {
            while(_node->_parent) //到根结点结束
            {
                //当前节点为父亲的左节点，则父亲就是下一个元素
                if(_node == _node->_parent->_left)
                {
                    _node = _node->_parent;
                    return *this;
                }
                    //为右节点，则表明以父节点为根的子树已经访问完了，往上查找
                else
                {
                    _node = _node->_parent;
                }
            }
            _node = nullptr;
        }
        return *this;
    }

    //后置++
    Self operator++(int)
    {
        Self copy = *this;
        ++(*this);
        return copy;
    }
    Self& operator--()
    {
        //end()
        if(_node == nullptr)
        {

        }
        //左子树不为空，则上一个元素为左子树的最右节点
        if(_node->_left)
        {
            _node = _node->_left;
            while(_node->_right)
            {
                _node = _node->_right;
            }
            return *this;
        }
        //左子树为空，当前子树已经访问过
        else
        {
            while(_node->_parent)
            {
                if(_node == _node->_parent->_right)
                {
                    _node = _node->_parent;
                    return *this;
                }
                else
                {
                    _node = _node->_parent;
                }
            }
            _node = nullptr;
            return *this;
        }

    }

    Self operator--(int)
    {
        Self copy = *this;
        --(*this);
        return copy;
    }
private:
    Node* _node;
};
///////////////////////////////////////////////////
//实现完RBTreeNode后，开始实现RBTree，而RBTree只希望被访问成员函数
//所以成员函数public，成员变量private
template <class K, class V, class KeyOfVal>
class RBTree
{
public:
    typedef RBTreeNode<V> Node;
    typedef RBTree_Iterator<V> iterator;

    //iterator begin
    iterator begin()
    {
        Node* cur = _root;
        while(cur && cur->_left)
        {
            cur = cur->_left;
        }
        return iterator(cur);
    }

    //iterator end
    iterator end()
    {
        return iterator(nullptr);
    }

    //插入节点
    bool insert(const V& data)
    {
        //空树
        if(_root == nullptr)
        {
            _root = new Node(data);
            //创建失败
            if(_root == nullptr)
            {
                perror("new error");
                return false;
            }
            //创建成功，根结点必须为黑色节点
            _root->_color = black;
            return true;
        }
        //不为空树
        else
        {
            Node* cur = _root;
            Node* parent = cur;
            KeyOfVal kov;
            while(cur)
            {
                if(kov(cur->_data) > kov(data))
                {
                    parent = cur;
                    cur = cur->_left;
                }
                else if(kov(cur->_data) < kov(data))
                {
                    parent = cur;
                    cur = cur->_right;
                }
                else
                {
                    perror("insert a same data, insert error");
                    return false;
                }
            }

            cur = new Node(data);
            if(kov(parent->_data) > kov(data))
            {
                parent->_left = cur;
            }
            else
            {
                parent->_right = cur;
            }
            cur->_parent = parent;
            //////////////////////////
            //判断颜色问题
            AssertColor(parent, cur);
            return true;
        }
        
    }
private:
    Node* _root = nullptr;
    //递归版本
    bool CheckNumB_R(Node* root, int num, int count)
    {
        if(root == nullptr)
        {
            if(num != count)
                return false;
            return true;
        }

        if(root->_color == black)
            ++count;

        return CheckNumB_R(root->_left, num, count) && CheckNumB_R(root->_right, num, count);
    }
    //非递归版本
    bool CheckNumB(Node* root)
    {
        vector<Node*> check; //检查是否右子树已经遍历过了，要记录所有走过的右侧的节点
        stack<Node*> s;      //存路径
        Node* cur = root;
        Node* pre = nullptr;
        int num = 0;         //记录黑色节点的个数
        int copy = -1;       //记录前一条路径的黑色节点的个数

        while(cur || !s.empty())
        {
            int flag = 0;

            while(cur)  //遍历每条路径
            {
                if(cur->_color == black)
                {
                    ++num;
                }
                s.push(cur);
                cur = cur->_left;
                flag = 1;
            }

            if(flag == 1) //说明走的路径是新的
            {
                if(copy != -1)
                {
                    if(copy != num) //前一个路径的黑色节点个数不等于当前路径的黑色节点个数，不满足条件，返回false
                        return false;
                }
                copy = num;
            }

            if(s.top()->_right == nullptr || CheckRepeated(check, s.top()->_right))  //右子树为空 / 右子树走过了，路径结束，换路径
            {
                if(s.top()->_color == black)
                {
                    --num;
                }
                s.pop();
            }
            else //右子树不为空，且没有走过，就去遍历右子树
            {
                cur = s.top()->_right;
                pre = cur;
                check.push_back(pre);
            }
        }
        //遍历完每条路径后，黑色节点个数都相等
        return true;

    }
    //检查右子树是否已经遍历过了
    bool CheckRepeated(vector<Node*>& check, Node*& pre)
    {
        for(auto e : check)
        {
            if(pre == e)
            {
                return true;
            }
        }
        return false;
    }


    //检查根是否为黑色
    bool CheckRoot()
    {
        if(_root == nullptr)
            return true;

        return _root->_color == black;
    }

    //检查是否有连续的红色节点
    bool CheckColor(Node* root)
    {
        if(root == nullptr)
            return true;
        return CheckColor(root->_left)
               && CheckColor(root->_right)
               && (root->_color == black || root->_parent->_color == black);
    }

    void AssertColor(Node*& parent, Node*& cur)
    {

        while(parent && parent != _root)
        {
            Node* grandfather = parent->_parent;
            Node* uncle = (parent == grandfather->_left) ? grandfather->_right : grandfather->_left;
            //插入位置的父亲为红色节点，需要处理
            if(cur->_color == red && parent->_color == red)
            {
                //叔叔存在，且为红
                if(uncle && uncle->_color == red)
                {
                    parent->_color = uncle->_color = black;
                    grandfather->_color = red;

                    cur = grandfather;
                    parent = cur->_parent;
                }
                    //叔叔存在,且为黑 / 叔叔不存在  旋转+变色
                else
                {
                    if(uncle == grandfather->_left)
                    {
                        if(cur == parent->_right)
                        {
                            RotationL(grandfather);
                            parent->_color = black;
                            grandfather->_color = red;
                        }
                        else
                        {
                            RotationR(parent);
                            RotationL(grandfather);
                            cur->_color = black;
                            grandfather->_color = red;
                        }
                    }
                    else
                    {
                        if(cur == parent->_left)
                        {
                            RotationR(grandfather);
                            parent->_color = black;
                            grandfather->_color = red;
                        }
                        else
                        {
                            RotationL(parent);
                            RotationR(grandfather);
                            cur->_color = black;
                            grandfather->_color = red;
                        }
                    }
                    break;
                }
            }
                //插入位置的父亲为黑色节点，不需要处理
            else
            {
                break;
            }
        }

        _root->_color = black;
    }
    void RotationL(Node* parent)
    {
        Node* pR = parent->_right;
        Node* pRL = pR->_left;

        parent->_right = pRL;
        if(pRL)
            pRL->_parent = parent;
        pR->_left = parent;
        Node* ppnode = parent->_parent;
        parent->_parent = pR;

        if(parent == _root)
        {
            _root = pR;
            pR->_parent = nullptr;
        }
        else
        {
            if(ppnode->_left == parent)
                ppnode->_left = pR;
            else
                ppnode->_right = pR;
            pR->_parent = ppnode;
        }

    }
    void RotationR(Node* parent)
    {
        Node* pL = parent->_left;
        Node* pLR = pL->_right;

        parent->_left = pLR;
        if(pLR)
            pLR->_parent = parent;
        pL->_right = parent;
        Node* ppnode = parent->_parent;
        parent->_parent = pL;

        if(_root == parent)
        {
            _root = pL;
            pL->_parent = nullptr;
        }
        else
        {
            if(ppnode->_left == parent)
                ppnode->_left = pL;
            else
                ppnode->_right = pL;
            pL->_parent = ppnode;
        }

    }
};

















//
// Created by 王有东 on 2024/4/7.
//
//////////////////////////////
#include <iostream>
#include <cassert>
#include <vector>
#include <stack>
using namespace std;
///红色
#define RED 1
///黑色
#define BLACK 2

///////////////////////////////
//定义红黑树的节点应该包含:
// 1. 树存的值_val
// 2. 树的颜色 _color
// 3. 指向孩子的指针 _left, _right
template <class T>
//必须定义为public，成员可以直接被使用
struct RBTreeNode
{
    RBTreeNode(const T& val)
        : _val(val)
        , _color(RED)
        , _left(nullptr)
        , _right(nullptr)
        , _parent(nullptr)
    {}

    typedef RBTreeNode<T> Node;
    T _val;
    int _color;
    Node* _left;
    Node* _right;
    Node* _parent;
};

////////////////////////////////
//定义红黑树，成员变量必须是节点的指针，以便创造节点
//且为了可维护性，要将成员变量定义为private
template <class T>
class RBTree
{
public:
    typedef RBTreeNode<T> Node;

    void InOrder()
    {
        _InOrder(_root);
        cout << endl;
    }

    //插入节点，按照二叉搜索树来
    bool insert(const T& val)
    {
        //空树
        if(_root == nullptr)
        {
            _root = new Node(val);
            _root->_color = BLACK;
            return true;
        }
        else
        {
            Node* cur = _root;
            Node* parent = cur;
            while(cur)
            {
                if(cur->_val < val)
                {
                    parent = cur;
                    cur = cur->_right;
                }
                else if(cur->_val > val)
                {
                    parent = cur;
                    cur = cur->_left;
                }
                else
                    return false;
            }

            //找到可以插入的位置cur
            cur = new Node(val);
            if(parent->_val < val)
            {
                parent->_right = cur;
            }
            else
            {
                parent->_left = cur;
            }
            cur->_parent = parent;

            //判断颜色,并改正
            AssertColor(parent, cur);

        }
        return true;
    }
    bool Check()
    {
        ////////非递归版本
        //return CheckRoot() && CheckColor(_root) && CheckNumB(_root);

        ////////递归版本
        Node* cur = _root;
        int num = 0;
        while(cur)
        {
            if(cur->_color == BLACK)
                ++num;
            cur = cur->_left;
        }

        return CheckRoot() && CheckColor(_root)
            && CheckNumB_R(_root, num, 0);
    }

private:
    Node* _root = nullptr;
    //递归版本
    bool CheckNumB_R(Node* root, int num, int count)
    {
        if(root == nullptr)
        {
            if(num != count)
                return false;
            return true;
        }

        if(root->_color == BLACK)
            ++count;

        return CheckNumB_R(root->_left, num, count) && CheckNumB_R(root->_right, num, count);
    }
    //非递归版本
    bool CheckNumB(Node* root)
    {
        vector<Node*> check; //检查是否右子树已经遍历过了，要记录所有走过的右侧的节点
        stack<Node*> s;      //存路径
        Node* cur = root;
        Node* pre = nullptr;
        int num = 0;         //记录黑色节点的个数
        int copy = -1;       //记录前一条路径的黑色节点的个数

        while(cur || !s.empty())
        {
            int flag = 0;

            while(cur)  //遍历每条路径
            {
                if(cur->_color == BLACK)
                {
                    ++num;
                }
                s.push(cur);
                cur = cur->_left;
                flag = 1;
            }

            if(flag == 1) //说明走的路径是新的
            {
                if(copy != -1)
                {
                    if(copy != num) //前一个路径的黑色节点个数不等于当前路径的黑色节点个数，不满足条件，返回false
                        return false;
                }
                copy = num;
            }

            if(s.top()->_right == nullptr || CheckRepeated(check, s.top()->_right))  //右子树为空 / 右子树走过了，路径结束，换路径
            {
                if(s.top()->_color == BLACK)
                {
                    --num;
                }
                s.pop();
            }
            else //右子树不为空，且没有走过，就去遍历右子树
            {
                cur = s.top()->_right;
                pre = cur;
                check.push_back(pre);
            }
        }
        //遍历完每条路径后，黑色节点个数都相等
        return true;

    }
    //检查右子树是否已经遍历过了
    bool CheckRepeated(vector<Node*>& check, Node*& pre)
    {
        for(auto e : check)
        {
            if(pre == e)
            {
                return true;
            }
        }
        return false;
    }


    //检查根是否为黑色
    bool CheckRoot()
    {
        if(_root == nullptr)
            return true;

        return _root->_color == BLACK;
    }

    //检查是否有连续的红色节点
    bool CheckColor(Node* root)
    {
        if(root == nullptr)
            return true;
        return CheckColor(root->_left)
        && CheckColor(root->_right)
        && (root->_color == BLACK || root->_parent->_color == BLACK);
    }

    void AssertColor(Node*& parent, Node*& cur)
    {

        while(parent && parent != _root)
        {
            Node* grandfather = parent->_parent;
            Node* uncle = (parent == grandfather->_left) ? grandfather->_right : grandfather->_left;
           //插入位置的父亲为红色节点，需要处理
           if(cur->_color == RED && parent->_color == RED)
           {
               //叔叔存在，且为红
               if(uncle && uncle->_color == RED)
               {
                   parent->_color = uncle->_color = BLACK;
                   grandfather->_color = RED;

                   cur = grandfather;
                   parent = cur->_parent;
               }
               //叔叔存在,且为黑 / 叔叔不存在  旋转+变色
               else
               {
                   if(uncle == grandfather->_left)
                   {
                       if(cur == parent->_right)
                       {
                           RotationL(grandfather);
                           parent->_color = BLACK;
                           grandfather->_color = RED;
                       }
                       else
                       {
                           RotationR(parent);
                           RotationL(grandfather);
                           cur->_color = BLACK;
                           grandfather->_color = RED;
                       }
                   }
                   else
                   {
                       if(cur == parent->_left)
                       {
                           RotationR(grandfather);
                           parent->_color = BLACK;
                           grandfather->_color = RED;
                       }
                       else
                       {
                           RotationL(parent);
                           RotationR(grandfather);
                           cur->_color = BLACK;
                           grandfather->_color = RED;
                       }
                   }
                   break;
               }
           }
           //插入位置的父亲为黑色节点，不需要处理
           else
           {
               break;
           }
       }

        _root->_color = BLACK;
    }
    void RotationL(Node* parent)
    {
        Node* pR = parent->_right;
        Node* pRL = pR->_left;

        parent->_right = pRL;
        if(pRL)
            pRL->_parent = parent;
        pR->_left = parent;
        Node* ppnode = parent->_parent;
        parent->_parent = pR;

        if(parent == _root)
        {
            _root = pR;
            pR->_parent = nullptr;
        }
        else
        {
            if(ppnode->_left == parent)
                ppnode->_left = pR;
            else
                ppnode->_right = pR;
            pR->_parent = ppnode;
        }

    }
    void RotationR(Node* parent)
    {
        Node* pL = parent->_left;
        Node* pLR = pL->_right;

        parent->_left = pLR;
        if(pLR)
            pLR->_parent = parent;
        pL->_right = parent;
        Node* ppnode = parent->_parent;
        parent->_parent = pL;

        if(_root == parent)
        {
            _root = pL;
            pL->_parent = nullptr;
        }
        else
        {
            if(ppnode->_left == parent)
                ppnode->_left = pL;
            else
                ppnode->_right = pL;
            pL->_parent = ppnode;
        }

    }
    void _InOrder(Node* root)
    {
        if(root == nullptr)
            return;
        _InOrder(root->_left);
        cout << root->_val << " ";
        _InOrder(root->_right);
    }
};






























#include <iostream>
using namespace std;
#include <vector>

namespace wyd
{
    template <size_t N>
    class bitset
    {
    public:

        bitset()
                : _bit(N / 32 + 1, 0)
        {}

        void set(const size_t& val)
        {
            size_t pos = val / 32;
            size_t bit = val % 32;
            _bit[pos] |= (1 << bit);
        }

        void reset(const size_t& val)
        {
            size_t pos = val / 32;
            size_t bit = val % 32;
            _bit[pos] &= ~(1 << bit);
        }

        bool test(const size_t& val)
        {
            size_t pos = val / 32;
            size_t bit = val % 32;
            return _bit[pos] & (1 << bit);
        }

    private:
        vector<int> _bit;
    };


    template<size_t N>
    class bit_two_set
    {
    public:
        void set(const size_t& val)
        {
            // 00 -> 01   0次 -》1次
            if(bit1.test(val) == 0
            && bit2.test(val) == 0)
            {
                bit2.set(val);
            }
            // 01 -> 10   1次 -》 2次
            else if(bit1.test(val) == 0
            && bit2.test(val) != 0)
            {
                bit1.test(val);
                bit2.reset(val);
            }
            else; //10  2次 / 以上

        }
        bool test(const size_t& val)
        {
            // 01 -> 1次
            if(bit1.test(val) == 0
            && bit2.test(val) != 0)
                return true;
            return false;
        }
    private:
        bitset<N> bit1;
        bitset<N> bit2;
    };
}#include <iostream>
using namespace  std;
extern int b = 10;
mybin:main.cpp  
	g++  -o result.out main.cpp  -std=c++11
.PHONY:clean
clean:
	rm -rf result.*
#pragma once
#include "HashTable.h"

namespace wyd
{
    template <class K, class V, class GetInt = GetInt<V>>
    class unordered_map
    {
        class MapOfKey
        {
        public:
            const K& operator()(const pair<K, V>& kv)
            {
                return kv.first;
            }
        };
    public:
        typedef typename HashList<K, pair<const K, V>, MapOfKey, GetInt>::iterator iterator;
        iterator begin()
        {
            return _h.begin();
        }
        iterator end()
        {
            return _h.end();
        }
        bool insert(const pair<const K, V>& kv)
        {
            return _h.insert(kv).second;
        }
        iterator find(const pair<const K, V>& kv)
        {
            return _h.find(kv);
        }
        iterator erase(const pair<const K, V>& kv)
        {
            return _h.erase(kv);
        }
        V& operator[](const K& key)
        {
            pair<iterator, bool> ret = _h.insert(pair<const K, V>(key, V()));
            return ret.first->second;
        }
        size_t size()const
        {
            return _h.size();
        }
        bool empty()const
        {
            return _h.empty();
        }
    private:
        HashList<K, pair<const K, V>, MapOfKey, GetInt> _h;
    };
}#pragma once
#include "HashTable.h"

namespace wyd
{
    template <class K, class GetInt = GetInt<K>>
    class unordered_set
    {
        class SetOfKey
        {
        public:
            const K& operator()(const K& key)
            {
                return key;
            }
        };
    public:
        typedef typename HashList<K, const K, SetOfKey, GetInt>::iterator iterator;
        iterator begin()
        {
            return _h.begin();
        }
        iterator end()
        {
            return _h.end();
        }
        bool insert(const K& key)
        {
            return _h.insert(key).second;
        }
        iterator find(const K& key)
        {
            return _h.find(key);
        }
        iterator erase(const K& key)
        {
            return _h.erase(key);
        }
        size_t size()const
        {
            return _h.size();
        }
        bool empty()const
        {
            return _h.empty();
        }
    private:
        HashList<K, const K, SetOfKey, GetInt> _h;
    };
}//模拟实现map
#include "NewRBTree.h"
template <class K, class V>
class mymap
{
    struct MapKeyOfT
    {
        const K& operator()(const pair<K, V>& kv)
        {
            return kv.first;
        }
    };
public:
    typedef typename RBTree<K, pair<K, V>, MapKeyOfT>::iterator iterator;
    iterator begin()
    {
        return _t.begin();
    }
    iterator end()
    {
        return _t.end();
    }
    bool Insert(const pair<K, V>& kv)
    {
        return _t.insert(kv);
    }
private:
    RBTree<K, pair<K, V>, MapKeyOfT> _t;
};
void test_map1()
{
    mymap<int, int> m;
    int a[] = { 4, 2, 6, 1, 3, 5, 15, 7, 16, 14 };
    for (auto e : a)
    {
        m.Insert(make_pair(e, e));
    }

   mymap<int, int>::iterator it = m.begin();
    while (it != m.end())
    {
        //it->first += 100;
        it->second += 100;

        cout << it->first << ":" << it->second << endl;
        ++it;
    }
    cout << endl;
}
//模拟实现set
#include "NewRBTree.h"
template <class K>
class myset
{
public:
   bool Insert(const K& val)
   {
       return _rb_tree.insert(val);
   }
private:
    struct FirstVal
    {
        const K& operator()(const K& val)
        {
            return val;
        }
    };
    RBTree<K, K, FirstVal> _rb_tree;
};#include <cstring>
#include <iostream>
#include <cassert>
using namespace std;
namespace MY
{
    class string
    {
    public:
        typedef char* iterator;

        iterator begin()
        {
            return _str;
        }
        iterator end()
        {
            return _str + _size;
        }

        string(const char* str = "")
                :_size(strlen(str))
                , _capacity(_size)
        {
//            cout << "string(char* str)" << endl;
            _str = new char[_capacity + 1];
            strcpy(_str, str);
        }

        void swap(string& s)
        {
            ::swap(_str, s._str);
            ::swap(_size, s._size);
            ::swap(_capacity, s._capacity);
        }
// 拷贝构造
        string(const string& s)
                :_str(nullptr)
        {
            cout << "string(const string& s) -- 深拷贝" << endl;
            string tmp(s._str);
            swap(tmp);
        }
// 赋值重载
        string& operator=(const string& s)
        {
            cout << "string& operator=(string s) -- 深拷贝" << endl;
            string tmp(s);
            swap(tmp);
            return *this;
        }
// 移动构造
        string(string&& s)
                :_str(nullptr)
                ,_size(0)
                ,_capacity(0)
        {
            cout << "string(string&& s) -- 移动构造" << endl;
            swap(s);
        }
// 移动赋值
        string& operator=(string&& s)
        {
            cout << "string& operator=(string&& s) -- 移动赋值" << endl;
            swap(s);
            return *this;
        }

        ~string()
        {
            delete[] _str;
            _str = nullptr;
        }

        char& operator[](size_t pos)
        {
            assert(pos < _size);
            return _str[pos];
        }

        void reserve(size_t n)
        {
            if (n > _capacity)
            {
                char* tmp = new char[n + 1];
                strcpy(tmp, _str);
                delete[] _str;
                _str = tmp;
                _capacity = n;
            }
        }

        void push_back(char ch)
        {
            if (_size >= _capacity)
            {
                size_t newcapacity = _capacity == 0 ? 4 : _capacity * 2;
                reserve(newcapacity);
            }
            _str[_size] = ch;
            ++_size;
            _str[_size] = '\0';
        }

        string& operator+=(char ch)
        {
            push_back(ch);
            return *this;
        }

        const char* c_str() const
        {
            return _str;
        }
    private:
        char* _str;
        size_t _size;
        size_t _capacity; // 不包含最后做标识的\0
    };
}//map的底层 是红黑树
//所以我们会使用map来封装一个红黑树
//map里是存放的键值对
#include "NewRBTree.h"

namespace wyd
{
    template <class K, class V>
    class map
    {
        struct MapOfVal
        {
            const K& operator()(const pair<const K, V>& data)
            {
                return data.first;
            }
        };
    public:
        typedef typename RBTree<K, pair<const K, V>, MapOfVal>::iterator iterator;

        bool insert(const pair<const K, V>& kv)
        {
            return _t.insert(kv);
        }

        iterator begin()
        {
            return _t.begin();
        }

        iterator end()
        {
            return _t.end();
        }

    private:
        RBTree<K, pair<const K, V>, MapOfVal> _t;
    };
}//set的底层 是红黑树
//所以我们会使用set来封装一个红黑树
//
#include "NewRBTree.h"

namespace wyd
{
    template <class K>
    class set
    {
        struct SetOfVal
        {
            const K& operator()( const K& data)
            {
                return data;
            }
        };
    public:
        typedef typename RBTree<K, const K, SetOfVal>::iterator iterator;
        bool insert(const K& data)
        {
            return _t.insert(data);
        }

        iterator begin()
        {
            return _t.begin();
        }

        iterator end()
        {
            return _t.end();
        }

    private:
        RBTree<K, const K, SetOfVal> _t;
    };
}#include "file.h"
int main()
{
    cout << b << endl;
    return 0;
}// 请模拟实现红黑树的插入--注意：为了后序封装map和set，本文在实现时给红黑树多增加了一个头结点
#include <iostream>
using namespace std;
enum Color
{
    red,
    black
};
template <class T>
struct RBTreeNode
{
    RBTreeNode(const T& data = T())
        : _left(nullptr)
        , _right(nullptr)
        , _parent(nullptr)
        , _data(data)
        , _color(red)
    {}
    RBTreeNode<T>* _left;
    RBTreeNode<T>* _right;
    RBTreeNode<T*> _parent;
    T _data;
    Color _color;
};
template<class T>
class RBTree
{
    typedef RBTreeNode<T> Node;
public:
    RBTree()
    {
        _pHead = new Node;
        _pHead->_pLeft = _pHead;
        _pHead->_pRight = _pHead;
    }

    // 在红黑树中插入值为data的节点，插入成功返回true，否则返回false
    // 注意：为了简单起见，本次实现红黑树不存储重复性元素
    bool Insert(const T& data)
    {
        //没有根结点
        Node* root = _pHead->_parent;
        if(root == nullptr)
        {
            root = new Node(data);
            root->_parent = _pHead;
            root->_color = black;
        }
        //有根结点
        else
        {
            Node* cur = root;
            Node* parent = root;
            while(cur)
            {
                if(cur->_data > data)
                {
                    parent = cur;
                    cur = cur->_left;
                }
                else if(cur->_data < data)
                {
                    parent = cur;
                    cur = cur->_right;
                }
                else
                {
                    return false;
                }
            }

            Node* newnode = new Node(data);
            if(parent->_data > data)
            {
                parent->_left = newnode;
            }
            else
            {
                parent->_right = newnode;
            }
            newnode->_parent = parent;

            //判断颜色
            AssertColor(parent, newnode);
        }

        //更新最左节点
        _pHead->_left = LeftMost();
        //更新最右节点
        _pHead->_right = RightMost();
        return true;
    }

    // 检测红黑树中是否存在值为data的节点，存在返回该节点的地址，否则返回nullptr
    Node* Find(const T& data)
    {
        Node* cur = GetRoot();
        while(cur)
        {
            if(cur->_data > data)
            {
                cur = cur->_left;
            }
            else if(cur->_data < data)
            {
                cur = cur->_right;
            }
            else
            {
                return cur;
            }
        }
        return nullptr;
    }


    // 检测红黑树是否为有效的红黑树，注意：其内部主要依靠_IsValidRBTRee函数检测
    bool IsValidRBTRee()
    {

    }
private:
    //判断颜色
    void AssertColor(const Node*& parent, const Node*& cur)
    {
        while(cur != _pHead->_parent)
        {
            //父亲是黑色节点，不会影响树的性质
            if(parent->_color == black)
            {
                return;
            }
            //父亲为红色节点，需要改变颜色
            else
            {
                Node* g_parent = parent->_parent;
                Node* uncle = g_parent->_left == parent ? g_parent->_right : g_parent->_left;
                //叔叔存在且为红
                if(uncle && uncle->_color == red)
                {
                    parent->_color = uncle->_color = black;
                    g_parent->_color = red;
                    cur = g_parent;
                    parent = cur->_parent;
                }
                    //叔叔存在且为黑 || 叔叔不存在
                else
                {

                }
            }
        }

        _pHead->_parent = black;
    }

    bool _IsValidRBTRee(Node* pRoot, size_t blackCount, size_t pathBlack)
    {

    }
    // 左单旋
    void RotateL(Node* pParent)
    {

    }
    // 右单旋
    void RotateR(Node* pParent)
    {

    }
    // 为了操作树简单起见：获取根节点
    Node*& GetRoot()
    {
        return _pHead->_parent;
    }
    // 获取红黑树最左侧节点
    Node* LeftMost()
    {
        Node* cur = _pHead->_parent;
        while(cur->_left)
        {
            cur = cur->_left;
        }
        return cur;
    }

    // 获取红黑树最右侧节点
    Node* RightMost()
    {
        Node* cur = _pHead->_parent;
        while(cur->_right)
        {
            cur = cur->_right;
        }
        return cur;
    }
private:
    Node* _pHead;
};
#include <iostream>
#include <string>
#include <fstream>

#include "compile_run.hpp"
#include "Parse.hpp"
#include "../Comm/Comm.hpp"

int main()
{
    // 1. 使用http协议（基于TCP）构建网络服务

    // 拿到代码
    std::string code;
    std::ifstream in("../Debug/debug.cc", std::ios::in);
    in.seekg(0, in.end);
    int size = in.tellg();
    in.seekg(0, in.beg);
    code.resize(size);
    in.read((char *)code.c_str(), size);
    // 序列化
    Json::Value out;
    out["code"] = code;
    // out["cin_nums"] = 
    out["cpu"] = 1;
    out["as"] = 20;
    Json::StyledWriter writer;
    std::string ser = writer.write(out);
    // 2. 拿出浏览器的请求正文
    std::string request_message = ser;
    std::string response_message;
    ns_complie_run::Comp_Run::Start(request_message, response_message);
    std::cout << response_message <<std::endl;

    FileOper::File::DeleteTemp();
    return 0;
}
#pragma once

#include <string>
#include <vector>
#include <unordered_map>
#include <atomic>
#include <fstream>

#include <cstring>
#include <cerrno>

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <unistd.h>
#include <fcntl.h>

#include <jsoncpp/json/json.h>

enum
{
    CodeEmpty = -3,
    Compile_Err, // 编译失败
    System_Call_Err,  // 系统调用失败
    Success   // 编译/运行成功
};

namespace TimeOper
{
    class time
    {
    public:
        // 获取秒级别的时间戳
        static std::string GetTimeStamp()
        {
            timeval tv;
            gettimeofday(&tv, nullptr);
            return std::to_string(tv.tv_sec);
        }
        // 获取毫秒级别的时间戳
        static std::string GetSusecondsTimeStamp()
        {
            timeval tv;
            gettimeofday(&tv, nullptr);
            return std::to_string(tv.tv_usec);
        }
    };
};

// 对文件的操作，如路径拼接、增添后缀
namespace FileOper
{
    const std::string temp_file_path = "./temp/";
    // 编译时需要的文件后缀
    const std::string src_name = ".cc";
    const std::string exe_name = ".exe";
    const std::string err_name = ".compile_err";
    // 运行时需要的文件后缀
    const std::string std_out = ".stdout";
    const std::string std_in = ".stdin";
    const std::string std_err = ".stderr";

    class File
    {
    public:
        // 拼接路径 file -> ../temp/file
        static std::string AddPath(const std::string &filename)
        {
            return temp_file_path + filename;
        }

// 编译时生成的临时文件 //

        // 形成.cc
        static std::string Src(const std::string &filename)
        {
            return AddPath(filename) + src_name;
        }

        // 形成.exe
        static std::string Exe(const std::string &filename)
        {
            return AddPath(filename) + exe_name;
        }

        // 形成.err
        static std::string Complie_Err(const std::string &filename)
        {
            return AddPath(filename) + err_name;
        }

// 运行时生成的临时文件 //

        //形成.stdout
        static std::string StdOut(const std::string &filename)
        {
            return AddPath(filename) + std_out;
        }

        //形成.stdin
        static std::string StdIn(const std::string &filename)
        {
            return AddPath(filename) + std_in;
        }
        
        //形成.stderr
        static std::string StdErr(const std::string &filename)
        {
            return AddPath(filename) + std_err;
        }

        // 判断.exe是否生成
        static bool IsFileExist(const std::string &filename)
        {
            struct stat statbuff;
            return stat(filename.c_str(), &statbuff) == 0;
            // 不可以穿nullptr，文件属性参数必须为非空参数
        }

// 拿到文件内容
        static bool GetfileMessage(const std::string &filename, std::string& message)
        {
            message.clear();

            std::ifstream in(filename, std::ios::in);
            if(!in.is_open()) return false;
            in.seekg(0, in.end);
            int size = in.tellg();
            in.seekg(0, in.beg);
            message.resize(size);
            in.read((char*)message.c_str(), size);
            return true;
        }
// 将内容写入文件
        static bool MessageToFile(const std::string& filename, const std::string& message)
        {
            std::ofstream out(filename, std::ios::out);
            if(!out.is_open()) return false;
            out.write(message.c_str(), message.size());
            out.close();
            return true;
        }

// 形成唯一的文件名, 利用毫秒级时间戳和原子性递增
        static std::string GetOwnFileName()
        {
            // 定义一个原子性的变量
            static std::atomic_uint am(0); 
            ++am; //原子性递增

            std::string time = TimeOper::time::GetSusecondsTimeStamp();
            return time + "_" + std::to_string(am);
        }

// 删除所有的临时文件
        static void DeleteTemp()
        {
            unlinkat(AT_FDCWD, "./temp", AT_REMOVEDIR);
        }
// 将信息使用Json序列化
        static std::string Serialize(int status, const std::string &message)
        {
            Json::Value out;
            out["status"] = status;
            out["result"] = message;
            Json::StyledWriter writer;
            std::string ser = writer.write(out);
            return ser;
        }
// 将response信息反序列化
        static void Deserialize(int& status, std::string &message, const std::string &response)
        {
            Json::Value in;
            Json::Reader reader;
            reader.parse(response, in);
            status = in["status"].asInt();
            message = in["result"].asString();
        }

    private:
    };
};

namespace ns_sign_to_message
{
    std::unordered_map<int, std::string> signal_error_map = 
    {
        {1, "SIGHUP: Hangup detected on controlling terminal or death of controlling process"},
        {2, "SIGINT: Interrupt from keyboard"},
        {3, "SIGQUIT: Quit from keyboard"},
        {4, "SIGILL: Illegal Instruction"},
        {5, "SIGTRAP: Trace/breakpoint trap"},
        {6, "SIGABRT: Aborted"},
        {7, "SIGBUS: Bus error (bad memory access)"},
        {8, "SIGFPE: Floating point exception"},
        {9, "SIGKILL: Killed"},
        {10, "SIGUSR1: User-defined signal 1"},
        {11, "SIGSEGV: Segmentation fault"},
        {12, "SIGUSR2: User-defined signal 2"},
        {13, "SIGPIPE: Broken pipe"},
        {14, "SIGALRM: Alarm clock"},
        {15, "SIGTERM: Terminated"},
        {16, "SIGSTKFLT: Stack fault on coprocessor (unused)"},
        {17, "SIGCHLD: Child process has terminated or stopped"},
        {18, "SIGCONT: Continue executing, if stopped"},
        {19, "SIGSTOP: Stop executing (cannot be caught or ignored)"},
        {20, "SIGTSTP: Stop from keyboard"},
        {21, "SIGTTIN: Background process attempting read"},
        {22, "SIGTTOU: Background process attempting write"},
        {23, "SIGURG: Urgent data available on socket"},
        {24, "SIGXCPU: CPU time limit exceeded"},
        {25, "SIGXFSZ: File size limit exceeded"},
        {26, "SIGVTALRM: Virtual timer expired"},
        {27, "SIGPROF: Profiling timer expired"},
        {28, "SIGWINCH: Window size change"},
        {29, "SIGIO: I/O is possible on a descriptor"},
        {30, "SIGPWR: Power failure (unused)"},
        {31, "SIGSYS: Bad system call"},
    };
};//本hpp用于输出我们日常测试函数的信息，比如一些错误信息，调试信息等\
写入到显示器或文件中，具体看我们想如何实现

#pragma once
#include <ctime>
#include <unistd.h>
#include <pthread.h>
#include <iostream>
#include <string>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdarg.h>
// 日志等级类别
enum Level
{
    Info,    // 正常
    Debug,   // 测试
    Warning, // 警告
    Error    // 错误
};

enum Mode
{
    DisPlay,  // 显示器
    OneFile,  // 一个文件
    ClassFile // 多种类型文件
};

class Log
{
public:
    void LogMessage(int mode, int level, const char *format, ...)
    {
        _level = level;
        _mode = mode;

        // 定义一个缓冲区，用于接收日志信息，最后分模式写入对应的文件
        char rignt[1024];
        // 定义可变参数列表
        va_list args;
        // 初始化可变参数列表,这一步是通过前一个参数的地址将可变参数列表中的各个参数都找到
        va_start(args, format);
        vsnprintf(rignt, sizeof(rignt), format, args);

        //现今buffer中就是日志的内容，但是我们将其组合成理想格式\
        ##level##[time][pid] : message
        std::string left = Get_Left_Message();

        std::string message = left;
        message += " : ";
        message += rignt;
        Print_Mode(message);
    }

private:
    time_t _time;        // 输出日志信息时的当地时间戳
    std::string _matter; // 输出的内容
    int _level;          // 日志等级
    int _mode;           // 输出的模式：显示器或文件输出
    pthread_t _tid;      // 线程tid

    void Print_Mode(std::string &message)
    {
        switch (_mode)
        {
        case DisPlay:
        {
            printf("%s", message.c_str());
        }
        break;
        case OneFile:
        {
            Print_OneFile(message);
        }
        break;
        case ClassFile:
        {
            Print_ClassFile(message);
        }
        break;
        default:
            printf("unknow mode ,error\n");
            break;
        }
    }

    void Print_OneFile(std::string &message)
    {
        //建立统一目录
        std::string dirname = "Log";
        mkdir(dirname.c_str(), 0775);

        umask(0);
        std::string filename = "./Log/log.";
        if (_mode == OneFile)
        {
            filename += "all";
        }
        else
        {
            switch (_level)
            {
            case Info:
                filename += "info";
                break;
            case Debug:
                filename += "debug";
                break;
            case Warning:
                filename += "warning";
                break;
            case Error:
                filename += "error";
                break;
            default:
                filename += "unknow";
                break;
            }
        }
        int fd = open(filename.c_str(), O_WRONLY | O_CREAT | O_APPEND, 0666);
        write(fd, message.c_str(), message.size());
        close(fd);
    }

    void Print_ClassFile(std::string &message)
    {
        Print_OneFile(message);
    }

    std::string Get_Left_Message()
    {
        char left_message[1024];
        snprintf(left_message, sizeof(left_message),
                 "[%s][%s][%s]",
                 Get_Level().c_str(),
                 Get_Local_Time().c_str(),
                 Get_Tid().c_str());
        return left_message;
    }

    std::string Get_Local_Time()
    {
        // 先获取时间戳
        _time = time(nullptr);
        // 将时间戳转换为当地时间
        tm *LocalTime = localtime(&_time);
        std::string local_time;

        local_time += std::to_string(LocalTime->tm_year + 1900);
        local_time += '-';

        local_time += std::to_string(LocalTime->tm_mon + 1);
        local_time += '-';

        local_time += std::to_string(LocalTime->tm_mday);
        local_time += ' ';

        local_time += std::to_string(LocalTime->tm_hour);
        local_time += ':';

        local_time += std::to_string(LocalTime->tm_min);
        local_time += ':';

        local_time += std::to_string(LocalTime->tm_sec);
        return local_time;
    }

    std::string Get_Tid()
    {
        return std::to_string((long long)pthread_self());
    }

    std::string Get_Level()
    {
        std::string slevel;
        switch (_level)
        {
        case Info:
            slevel = "Info";
            break;
        case Debug:
            slevel = "Debug";
            break;
        case Warning:
            slevel = "Warning";
            break;
        case Error:
            slevel = "Error";
            break;
        default:
            slevel = "UnKnow";
            break;
        }
        return slevel;
    }
};
